AmiTCP/IP System Manual Revision: 2.4 amitcp-group@hut.fi Tomi Ollila Pekka Pessi Markus Peuhkuri Jarno Rajahalme August 13, 1993 Foreword What Is AmiTCP/IP The Programming Project is a software engineering course here at Helsinki University of Technology. A group of 3---4 students designs, implements and tests a complete working software system during this course. Our purpose was to provide a free TCP/IP implementation for all Amiga users. Lack of a standard networking interface was anirritating shortcoming of the Amiga systems. AmiTCP/IPis a protocol stack implementing basic Internet protocols on top of any SANA-II network device driver(for Ethernet, SLIP, etc.). The protocol stack offers the standard Berkeley Socket application program interface (API) to the TCP/IP protocolsimplemented as an Amiga shared library. Using AmiTCP/IP and appropriate client program you can connect to any services available on your TCP/IP network. How Is This Achieved At first we planned to write the whole protocol stack from scratch. After examining standards about TCP/IP and bibliography about its implementations we become aware of the possibility of using the BSD NET/2 code as a base of our work. We discussed about the idea and found good reasons why the BSD code should be used. Eventually wedecided to take that path with the project. AmiTCP/IPis built around BSD NET/2 networking code. Because the networking part of the BSD UNIX kernel is rather isolated, only a few kernel routines had to be rewritten to suit the architecture of the AmiTCP/IP. SANA-II and shared library interfaces were added to the bottom and top of the modified NET/2 code, respectively. Why Is the BSD Code Used Here are some of the pros of the decision: fflWe don't need to reimplement the most complex part (and all the bugs) of the system. i fflWe noticed that the BSD kernel support for the networking part is easy enough to implement using powerful Amiga features. fflWhen improvements are done to the NET/2 code, we can improve AmiTCP/IP by simply replacing the old code with the changed one. fflWe are offering the socket application interface. It is the most used interface in networking programs with TCP/IP. Using the NET/2 code makes it easy to implement the BSD socket related function call interface as our API. fflWe can easily port crucial network utilities from the BSD. About SANA-II Bottom level interface to the SANA-II device drivers was an obvious choice. SANA-II is the Amiga standard interface for network devices, and most manufacturers are shipping SANA-IIcompatible device drivers for their hardware. There are also some freely distributable SANA-II drivers e.g. for the standard serial interface. Althoughthere may be few problems with different network types the AmiTCP/IP should be able to use all SANA-II device drivers which support IP. Release 2.0 This release of AmiTCP/IP includes onlythe protocol stack (AmiTCP), test programs, basic network utilities and example client and servers. The distribution still lacks most basicclient and server programs. The second release of the AmiTCP/IP contains some improvements and bug fixes over the first release. It is incompatible withprevious version in binary level, however. Old applications and the newlibrary DO NOT work together. If you have an application compiled with previous version of AmiTCP/IP, it MUST be recompiled. We hope that thisis the only downward incompatible release. The AmiTCP/IP Group requests all users of the AmiTCP/IP to return any new applications or improved versions tothe AmiTCP/IP Group, , and grant it theright to redistribute them. ii Acknowledgments We would like to thank fflComputer Systems Research Group from University of California, Berkeley, for developing BSD Unix system. fflCarnegie Mellon University for Mach bsdss port of BSD Net/2. fflAntti Louko , our project supervisor, from the Computing Centre of the Helsinki University of Technology. fflJukka Partanen for providing the GNU CC cross-compiling environment for the Amiga in the HP 9000/700 workstations. fflTimo Rossi for providing the SANA-II drivers for Western Digital Ethernet cards used in testing. Further on, Jarno and Markus would like to thank their wives Maarit and Katri for forgiving those late nights (or early mornings) that we spent with this project. iii AmiTCP/IPcontains material derived from BSD net/2 release. The following acknowledgement should be included in all AmiTCP/IP distributions: Copyright cfl1982, 1986, 1988, 1990 Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. iv Some codeof the AmiTCP/IP originates from the BSDSS 4 by CMU, which is hereby acknowledged: Mach Operating System. Copyright cfl1992 Carnegie Mellon University. All Rights Reserved. Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in allcopies of the software, derivative works or modified versions, and any portions thereof, and that both notices appear in supporting documentation. CARNEGIE MELLON ALLOWS FREE USE OF THISSOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON DISCLAIMS ANYLIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. Carnegie Mellon requests users of this software to return to Software Distribution Coordinator School of Computer Science Carnegie Mellon University Pittsburgh PA 15213-3890 or Software.Distribution@CS.CMU.EDU any improvements or extensions that theymake and grant Carnegie Mellon the rights to redistribute these changes. v vi About This Manual How This Manual Is Organized We have tried to organize this manual sothat you are not forced to read material that you are not interested in. In order to achieve this we have divided the text into following chapters: 1. User's Manual gives you basic information about using the AmiTCP/IP system. Descriptions about our debugging tools qwriter and agnet.device is also included here. 2. Interfaces describes briefly all external interfaces of the AmiTCP/IP. 3. Programmer's Manual gives you the needed information to use AmiTCP/IP to make your own network-aware programs. 4. Internal Description gives you information about the internal structure of the AmiTCP/IP-system. This is meant for all of you who are interested in the internal design of the AmiTCP/IP. 5. Implementation Notes is written for those of you who are going to maintain AmiTCP/IP or plan to develop it further. There arealso two appendices, the user and programmer reference guides. These appendices are in the AutoDoc format andthey are also available in machine readable form. If you have trouble understanding the jargon1 or TLAs1 refer to the glossary at the end of this manual. Typographical Conventions To help you to understand the text in this manual, following typefaces and punctuation are used: Roman is the basic typeface used throughout the text. Slanted is used in text which we want youto take special attention on. Italics is used to introduce new terms and concepts which will be explained shortly. Italics is also used to refer to the names of the publications and tothe sections of this manual. Typed Text is used for literal program codeand items specific to the implementation, such as functionnames, identifiers and C language keywords. Bold text is used to refer to specificfiles and command names used by AmiTCP/IP. ________________________________ 1See glossary. vii Syntax Conventions There are few syntactic conventions usedin this manual: [:::] Square brackets are used for bibliographical references, list of which can be found from the end of this manual. hargumenti User supplied required argumentsare printed between angle brackets. [argument] User supplied optional argumentsare printed between square brackets. function() C function names are followed bya pair of parenthesis. The preprocessor macros---as opposedto the genuine functions---are in upper case. viii GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyoneis permitted to copy and distribute verbatim copies of this license document, but changing it is notallowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software---to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is coveredby the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designedto make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or ifyou modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, foreach author's protection and ours, we want to make certain that everyone understands that there isno warranty for this free software. If the software is modified by someone elseand passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally,any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, ineffect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. ix TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The ``Program'', below, refers to any such program or work, and a ``work based on the Program'' means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) Each licensee is addressed as ``you''. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: (a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of anychange. (b) You must cause any work that you distribute or publish,that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge toall third parties under the terms of this License. (c) if the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright noticeand a notice that there is no warranty (or else, saying thatyou provide a warranty) and that users may redistribute theprogram under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to printan announcement.) x These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: (a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the termsof Sections 1 and 2 above on a medium customarily used forsoftware interchange; or, (b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code,to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, (c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only ifyou received the program in object code or executable formwith such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. xi If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made xii generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR xiii DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS xiv Contents 1 User's Manual 1 1.1 Installation : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : 1 1.1.1 Using the SLIP Drivers: : : : : : : : : : : : : : : : : : : : : * *: : : : 2 Common Problems with the SLIP Driver And AmiTCP/IP : : : : 2 1.2 Configuration : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 3 1.2.1 Options : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 4 1.2.2 Network Database : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : 4 1.3 Internet Addressing : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 4 1.3.1 Internet Dot Notation : : : : : : : : : : : : : : : : : : : : : * *: : : : 5 1.3.2 Nets and Routing : : : : : : : : : : : : : : : : : : : : : : : :* * : :: : : 5 1.3.3 Subnets : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 6 1.3.4 Broadcast Addresses : : : : : : : : : : : : : :: : : : : : : : :* * : : : : 6 1.4 Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 7 1.4.1 arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 7 1.4.2 ifconfig : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 7 1.4.3 letnet: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 8 1.4.4 netstat : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 8 1.4.5 NapsaTerm : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 8 1.4.6 offline : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 9 1.4.7 online: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 9 1.4.8 route : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 9 1.5 Errors and Logging : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 9 1.6 Troubleshooting : : : :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 10 1.7 Testing Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 10 1.7.1 Agnet : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 10 ARexx Port for agnet.device : : : : : : : :: : : : : : : : : : :* * : : 11 1.7.2 Qwriter : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 13 Command Line Options : : : : : : : : : : : : : : : : : : : : : :* * : :: : 13 2 Interfaces 15 2.1 AmiTCP/IP Processes : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 15 2.2 Application Interface : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : 16 2.3 SANA-II Interface : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 16 2.3.1 Interface ioctls : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : 17 2.4 Configuration Files : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 17 2.5 ARexx Interface : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 17 2.5.1 Commands : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 18 2.5.2 Variables : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 19 Boolean variables : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : 23 xv CONNECTIONS output format : : : : : : : : : : : : : : : : : : : * *: : : 24 ICMPHIST output format: : : : : : : : : : : : : : : : : : : : : * *: : : : 24 3 Programmer's Manual 27 3.1 Socket Concepts : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 27 3.1.1 Socket Types : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : :: 27 3.1.2 Using The Socket Library : : : : : : : : : : : : : : : : : : : :* * : : : 28 3.1.3 Compiling and Linking The Applications: : : : : : : : : : : : : * * 30 The NETINCLUDE Header Files : : : : : : : :: : : : : : : : : : :* * : : 30 Linking With net.lib : : : : : : : : : : : : : : : : : : : : : :* * : :: : 32 3.1.4 Socket Creation : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : 32 3.1.5 Binding Local Names : : : : : : : : : :: : : : : : : : : : : : :* * : : : : 33 3.1.6 Connection Establishment : : : : : : : : : : : : : : : : : : : :* * : : : 34 3.1.7 Data Transfer : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 36 3.1.8 Discarding Sockets: : : : : : : : : : : : : : : : : : : : : : : * *: : : : : 36 3.1.9 Connectionless Sockets: : : : : : : : : : : : : : : : : : : : : * *: : : : 37 3.1.10 Input/Output Multiplexing :: : : : : : : : : : : : : : : : : : * *: : : 38 3.2 Network Library Routines : : : : : : : : : : : : : : :: : : : : : : : :* * : : : : 40 3.2.1 Host Names : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 40 3.2.2 Network Names : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 41 3.2.3 Protocol Names :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 41 3.2.4 Service Names : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 42 3.2.5 Miscellaneous :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 42 Remote Login Client Code : : : : : : : : : : : : : : : : : : : :* * : : : 42 3.3 Client/Server Model : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 44 3.3.1 Servers : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 45 3.3.2 Clients : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 47 3.3.3 Connectionless Servers: : : : : : : : : : : : : : : : : : : : : * *: : : : 48 Ruptime Output :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 48 3.4 Advanced Topics : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 51 3.4.1 Out Of Band Data : : : : : : : : : : : : : : : : : : : : : : : :* * : :: : : 51 3.4.2 Non-Blocking Sockets : : : : : : : : : : : : : : : : : : : : : :* * : : : : 53 3.4.3 Signal Driven Socket I/O : : : : : : : : : : : : : : : : : : : :* * : : : 54 3.4.4 Selecting Specific Protocols : : : : : : : : : : : : : : : : : :* * : : 55 3.4.5 Address Binding : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : 55 3.4.6 Broadcasting And Determining Network Configuration : : : : 58 AmiTCP/IP specific extensions : : : : : : : : : : : : : : : : : * *: : 60 Extensions to interface ioctls: : : : : : : : : : : : : : : : : * *: : 60 3.4.7 Socket Options :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 61 3.4.8 Inetd : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 62 3.5 Deviation From Berkeley Sockets: : : : : : : : : : : : : : : : : : : : * *: : : 63 3.5.1 Opening and Closing the Shared Library: : : : : : : : : : : : : * * 63 3.5.2 Naming Conventions of the API Functions : : :: : : : : : : : : * *63 3.5.3 errno : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 64 3.5.4 New Field in the sockaddr Structures : : : : : : : : : : : : : :* * 64 3.5.5 Linger Time : : : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : : 64 3.5.6 Transferring Sockets from a Task to Another : :: : : : : : : 64 3.5.7 Ioctl Differences : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : 65 3.5.8 Signal Handling : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : 65 3.5.9 Asynchronous I/O : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : 66 3.5.10 Constructing an Event Loop: : : : : : : : : : : : : : : : : : : * *: : : 66 xvi 3.5.11 ''Killing'' the Processes : : : : : : : : : : : : : : : : : : : * *: : : 67 3.5.12 WaitSelect() : : : : : : : : : : : : : : : : : : : : : : : : : :* * :: : : : : 67 4 Internal Description 69 4.1 Source File Structure : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : 69 4.1.1 System Include Files : : : : : : : : : : : : : : : : : : : : : :* * : :: : 69 4.1.2 Protocol Independent Network Routines : : : : : : : : : : : : : * * 70 4.1.3 Internet Protocol Modules : : : : : : : : : : : : : : : : : : : * *: : : 71 4.1.4 BSD Kernel Service Modules: : : : : : : : : : : : : : : : : : : * *: : : 72 4.1.5 BSD Socket API: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 73 4.1.6 Miscellaneous Files : : : : : : : : : : : : : :: : : : : : : : :* * : : : : 75 4.2 AmiTCP/IP Initialization : : : : : : : : : : : : : : : : : : :: : : : :* * : : : : 75 4.2.1 init_all() : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 76 4.2.2 deinit_all() : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : :: 77 4.3 The Main Module : : : :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 77 4.4 Protocol Entities : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 78 4.5 Memory Management : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 79 4.5.1 Mbuf Functions :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 79 4.6 Concurrency Control : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 82 4.7 Network Device Drivers : : : : :: : : : : : : : : : : : : : : : : : : * *: : : : : 83 4.7.1 SANA-II Soft Network Interface: : : : : : : : : : : : : : : : : * *: : 84 4.7.2 ARP : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 87 4.8 Logging : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 88 4.9 ARexx Interface : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 89 4.10 Application Interface Concepts : :: : : : : : : : : : : : : : : : : : * *: : : 90 4.10.1 SocketBase -- an Extension of the Task Structure : : : : : 90 4.10.2 The System Call Semaphore and Task Priorities : : : : : : : 90 4.11 Configuration Variables : : : : :: : : : : : : : : : : : : : : : : : : * *: : : : : 91 4.12 Network Database : : : : : : : : : : : : : : : : : : : : :: : : : : : :* * : : : : : : 92 5 Implementation Notes 93 5.1 Time outs : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :: 93 5.2 Memory Management : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 95 5.2.1 Mbufs : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 95 5.2.2 malloc() & free() : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : 95 5.3 Concurrency Control : : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 96 5.3.1 Processor Priority Levels : : : : : : : : : : : : : : : : : : : * *: : : 96 5.3.2 Sleeping Facilities : : : : : : : : : : : : : :: : : : : : : : :* * : : : : 97 5.4 Socket Library Creation Procedure : : : : : : : : : : : : : : : : : : :* * : : 99 5.4.1 Master Library Base : : : : : : : : : :: : : : : : : : : : : : :* * : : : : 99 5.4.2 Application Library Bases : : : : : : : : : : : : : : : : : : : * *: : : 99 5.5 The SocketBase Structure : : : : : : : : : : : : : : :: : : : : : : : :* * : : : : 100 5.6 The Application Program Interface : : : : : : : : : : : : : : : : : : :* * : : 102 5.6.1 How API Functions Are Ported : : : : : : : : : : : : : : : : : :* * : :102 5.6.2 API Functions Which Needed More Modifications : : : : : : : 103 5.7 Changes in Functions Below API Level : : : : : : : : : : :: : : : : : :* * : 103 5.7.1 Other Changes : : : : :: : : : : : : : : : : : : : : : : : : : * *: : : : : : 103 5.8 Agnet.device : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : 104 5.8.1 IO Commands : : : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : : 104 5.8.2 Initialization Procedure : : : : : : : : : : : : : : : : : : : :* * : : : 106 5.8.3 The Device Interface Functions: : : : : : : : : : : : : : : : : * *: : 107 xvii Opening an Unit : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 107 Closing an Unit : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 107 Initiating an IO Request : : : : : : : : : : : : : : : : : : : :* * : : :108 Aborting an IO Request: : : : : : : : : : : : : : : : : : : : : * *: : : : 108 Expunging the Device : : : : : : : : : : : : : : : : : : : : : :* * : :: : 108 5.8.4 Packet Delivery : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : 109 5.8.5 Arexx Interface : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : 109 A Autodocs for Network Applications and Utilities 111 A.1 Network Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 112 A.1.1 arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 112 A.1.2 ifconfig : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 114 A.1.3 inetd : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 117 A.1.4 letnet: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 119 A.1.5 offline : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 120 A.1.6 online: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 121 A.1.7 ping : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : : 122 A.1.8 route : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 126 B API Function Reference 128 B.1 Standard BSD Style Socket Functions: : : : : : : : : : : : : : : : : : * *: : 130 B.1.1 accept() : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 130 B.1.2 bind(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 132 B.1.3 CloseSocket() :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 133 B.1.4 connect() : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 134 B.1.5 Dup2Socket() : : : : : : : : : : : : : : : : : : : : : : : : : :* * :: : : : : 136 B.1.6 getpeername() :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 137 B.1.7 getsockname() :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 138 B.1.8 getsockopt() : : : : : : : : : : : : : : : : : : : : : : : : : :* * :: : : : : 139 B.1.9 IoctlSocket() :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 142 B.1.10 listen() : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 144 B.1.11 recv(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 145 B.1.12 select() : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 147 B.1.13 send(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 150 B.1.14 shutdown(): : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 152 B.1.15 socket() : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 153 B.2 Other BSD Functions Related to Sockets : : : : : : : : : : : : : : : : * *: 156 B.2.1 getdtablesize() : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 156 B.2.2 Syslog() : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 157 B.3 Network Data and Address Manipulation : : : : : : : : : : : : : : : : :* * : 159 B.3.1 inet_addr() : : : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : : 159 B.4 Network, Protocol and Service Queries : : : : : : : : : : : : : : : : :* * : 162 B.4.1 gethostbyname() : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 162 B.4.2 getnetbyname(): : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 164 B.4.3 getprotobyname() : : : : : : : : : : : : : : : : : : : : : : : :* * : :: : : 166 B.4.4 getservbyname() : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 167 B.5 AmiTCP/IP Specific Extensions : : : : : : : : : : : : : : : : : : : : :* * : : : 169 B.5.1 Errno() : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 169 B.5.2 ObtainSocket(): : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 170 B.5.3 ReleaseCopyOfSocket() : : : : : : : : : : : : : : : : : : : : : * *: : : : 171 B.5.4 ReleaseSocket() : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 172 xviii B.5.5 SetDTableSize() : : : : : : : : : : : :: : : : : : : : : : : : :* * : : : : : 173 B.5.6 SetErrnoPtr() :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 174 B.5.7 SetSocketSignals(): : : : : : : : : : : : : : : : : : : : : : : * *: : : : : 175 C AmiTCP/IP Network Link Library 176 C.1 net.lib Functions : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : 177 C.1.1 autoinit : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 177 C.1.2 autoinitd : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 178 C.1.3 charRead : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 179 C.1.4 gethostname : : : : : : : : : : : : :: : : : : : : : : : : : : :* * : : : : : : 181 C.1.5 lineRead : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : 182 D Protocols and Network Interfaces 185 D.1 Protocols and Network Interfaces : : : : : : : : : : : :: : : : : : : :* * : : 186 D.1.1 arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 186 D.1.2 icmp : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : : 189 D.1.3 if : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : :190 D.1.4 inet : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* *: : : : : : : : 193 D.1.5 ip : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : :196 D.1.6 lo : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : :198 D.1.7 routing : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : 199 D.1.8 tcp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 201 D.1.9 udp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :* * : : : : : : : : 203 Glossary 205 Bibliography 209 xix xx Chapter 1 User's Manual 1.1 Installation AmiTCP/IP installation is made by standard Commodore Amiga Installer which provides an easy installation. Before you can proceed, you should acquire some information, list of whichfollows. Your should ask your local network administrator for few things to be able to connect your Amiga to a network. Take this page or copy of it with you to make sure that you don't forget anything: 1. Internet protocol address allocated for your computer. This is a series of four decimal numbers separated by dots. For example, ``130.233.161.40'' is a legal internet address. 2. Destination IP address of a point--to--point link. This applies only if you use a point--to--point medium, such as a serial line. 3. Netmask for your network1 This determines which part of your internet address is used to specify the network. Netmask is like ``255.255.255.0''. If you do not supply this value, a default computed from the IP address is used. 4. Name of your host. This is a mnemonic name which can usually be used instead of the internet address to refer to your computer. This is like ``Amiga1''. 5. Domain name of your site. For example, ``hut.fi'' is the domain name for the Helsinki University of Technology in Finland. 6. Address(es) of the Domain Name Server(s) which will be used to translate host names to corresponding internet addresses. A local host database must be used instead if there is no name server on your domain. 7. Address of the default gateway via which to send packets to the hosts not on your local network. There may be more than one of them. ________________________________ 1Netmask is usually needed onlyif you are connected to several networks or a network capable to broadcasts. 1 2 Section 1.1 AmiTCP/IP System Manual 8. The network interface to use. This may be Ethernet, SLIP or something else. We assume that you have proper hardware installed and the appropriate Sana-II compatible device driver installed in directory Devs:networks. AmiTCP/IP needs the name of the device driver in order to use it. The unit number for the device in question is also needed (usually this is 0). Installation starts by double-clicking the Install_AmiTCP-2.0-icon of the distribution disc. You can select the level whichspecifies how many choices are left to you by the installation script. After a successful installation your computer is ready to communicate with the network. See the file README.FIRST for more information about the installation procedure. If you plan to compile applications which use AmiTCP/IP, you should add two AmigaDOS assigns for the compiler to find appropriate files. Assign the name NETINCLUDE: to the netinclude directory of the AmiTCP/IP and the name NETLIB: to the directory netlib. 1.1.1 Using the SLIP Drivers Some Commodore-Amiga Networking Group supplied SANA-II drivers are distributed with the AmiTCP/IP. The SLIPdrivers included are taken from Olaf Seibert's distribution and has somebug fixes over the version 37.3. See the file doc/slip.doc for installinginstructions for these drivers. The version number of the included slip.device is 37.4. You can use this or newer SLIP driver with AmiTCP/IPwith certain precautions. The included CSLIP device is similar to theSLIP device, it only uses the Van Jacobson header compression (see [Jacobson 1990 ] fordescription of this compression method). If your network connection supports CSLIP, you can use cslip.device instead of slip.devicein all examples given in this section. Used serial interface, baud rate and other parameters for the unit 0 of the SLIP device are specified in the configuration file ENV:Sana2/slip0.config. You must edit this file according your system setup before you can use the slip device. Copy the edited file to both ENVARC:Sana2 and ENV:Sana2 directories. The AmiTCP/IP opens the slip device driver when given a following ifconfig2 command: ifconfig slip.device/0 local-address remote-address The local-address is the IP address (orname) given to your host, the remote-address is the IP address (or name) of the host you are connecting to with the serial line. You should also add a routingentry with the route command, for example route add default remote-address You can test your SLIP connection immediately with the command ping remote-address ________________________________ 2The ifconfig and route commands like described here are normally placed to the startnet script during AmiTCP/IP installation. System Manual AmiTCP/IP Section 1.2 3 Common Problems with the SLIP Driver AndAmiTCP/IP The ifconfig command gives you the following error message, if there is some problems opening the interface: ifconfig: ioctl (SIOCGIFFLAGS): no suchinterface If the device driver is not installed properly or there is no configuration file, AmiTCP/IP gives thefollowing log message: <3> OpenDevice: Device or unit failed toopen In this case, you should check that thefile ENV:Sana2/slip0.config actually exists and the device driver isin the correct directory. If the device driver is ok, but the needed serial device is busy (or you have set the slip driver to offlinestate), AmiTCP/IP logs the following message: <3> slip.device: Device driver is offline (Unit is currently offline) Then you must free the serial interface,set the slip device to the online state and give the previous ifconfig command with the ``up'' option3 again. If AmiTCP/IP gives no error messages and the serial link still does not work, it may be due to incorrect information in the ENV:Sana2/slip0.config-file. Check thatthe baud rate is correct. Note that the slip device loads the configuration file only on startup, which means that you must restart the AmiTCP/IP if you have already configured the slip driver with an ifconfig command. 1.2 Configuration AmiTCP/IP is normally started from the command line with a startup script. It starts the AmiTCP/IP process, which loads the configuration files. The script also contains ifconfig and route commands to open the SANA-II device drivers and add the needed route entries, respectively. The AmiTCP/IP can be configured with both option files and ARexx commands. The option files are stored in the text format and they can be edited with any text editor. The '#' character startsa comment, which continues to the end of the line. All configuration commands are presented in the section 2.4 starting from the page 17. Configuration files for AmiTCP/IP are stored in the directory AmiTCP:db. It contains at least following files: AmiTCP:db/AmiTCP.config AmiTCP/IPinternal configuration. AmiTCP:db/netdb Network database information, ie. host names, networks, services, protocols, domain name servers and domains. ________________________________ 3The up is needed because the AmiTCP/IP implicitly adds this option when an address to the interface is first given. If the second ifconfig specifies the same address as before, the up option must be given explicitly. 4 Section 1.3 AmiTCP/IP System Manual AmiTCP:db/hosts.equiv Host equivalence data used by rlogind, rshd etc. (these daemons are currently unimplemented). AmiTCP:db/inetd.conf Services provided by Inetd, the internet super server. 1.2.1 Options Normally AmiTCP/IP reads options from the file AmiTCP:db/AmiTCP.config. You can specify an option file also on the command line (eg. AmiTCP WITH myopts) or with the tool type WITH. Youcan prevent AmiTCP/IP from loading the default option file by the NOCONFIG command line option. 1.2.2 Network Database The file AmiTCP:db/netdb is used to store the local net and host name information. There is an example file in the distribution, which you must change according to your local network environment. The syntax for the network database file is same as thesyntax for the Arexx command add (see page 19). The mostimportant entries are the name of your own host and the important hosts in your local net. For instance, if your host name is amiga1.hut.fi and your internet address(IP number) is 130.233.61.50, then there is probably a following linein your AmiTCP:db/netdb file: HOST 130.233.61.50 amiga1.hut.fi amiga1 amy1 The firstentry after the keyword HOST is the internet address of your host. It is followed by the official name and an optional list of alias names to your host. Normally,all host and network names will be translated to the actual internet addresses by a name server. If you can not use the name service, then all host names must be inthe AmiTCP:db/netdb file or in an included file. In that case it may be easiest to copythe /etc/hosts file from a nearby Unix machine. You can add host names to the network database with ARexx commands at any time. For instance, the following command adds a host called vipunen: rx "address AMITCP add host 130.233.224.20 vipunen.hut.fi vipunen" There arealso service and protocol entries in the network database files. Do not change them if you are not an expert user. 1.3 Internet Addressing Each host in the Internet must have an unique 32 bit binary address. This address identifies the location ofhost in the internet in an unambiguous way. The internet address is divided intoa net part and a host part. Because of this elegant feature a single address identifies a unique host as well as the network whichthe computer is connected to. System Manual AmiTCP/IP Section 1.3 5 When selecting a route to a particular host the whole address is considered first. If no direct route to the host can be found, a route to the host's network can be considered. If no route to either host or net can be found, the packet is sent tothe default gateway. Because the the internet address defines also the network which the computer is connected, they must actually be given one per network connection. If a host is directly connected to severalnetworks, it has also several distinct internet addresses. 1.3.1 Internet Dot Notation Since it is rather inconvenient to use 32-bit integers, the internet address is normally written in the Internet dot notation. It is a series of decimal numbers separated by dots. ____________________________________________________ !_Format__!Size______________________!Example_______! ! a !32-bit !169510179 ! ! a.b !8-bit.24-bit !10.1738019 ! ! a.b.c !8-bit.8-bit.16-bit !10.26.34083 ! !_a.b.c.d_!8-bit.8-bit.8-bit.8-bit_!_10.26.133.35_!_ Table 1.1: Four different forms for an Internet address. The one with four separate octets is the most common form of the notation. See the reference for the function bsdsocket.library/inet_addr() to additional information (at Appendix B.3.1, page 159). 1.3.2 Nets and Routing 0_1_2_3_4______8_____________16____________24___________31_ ! ! ! ! Class A !!0!!Netpart !! Hostpart !! __________________________________________________________ __________________________________________________________!!!!! Class B !!1!!0!! Netpart !! Hostpart !! __________________________________________________________ __________________________________________________________!!!!!! Class C !!1!!1!!0!! Netpart !! Hostpart !! __________________________________________________________ __________________________________________________________!!!!!! Class D !!1!!1!!1!!0!! Multicast Address !! __________________________________________________________ __________________________________________________________!!!!!* *!! Class E !!1!!1!!1!!1!!0!! Experimental Address !! __________________________________________________________ Figure 1.1: The Internet address classes. The different address classes can be identified by few first bits. 6 Section 1.3 AmiTCP/IP System Manual There arefive classes of internet addresses in use, namely A, B, C, D and E classes. The difference between address classesis the length of the network and host part. An A class address has 7 bits for net address and 24 bits for host address, a B classaddress has 14 bits for net and 16 bits for host and a C class address has 21 bits for net and 8 bits for host. The D class is used for the IP multicast addresses and the E class for experimental use only4. The address class can be determined by the first octet of the address. If it is in the range 0---127, the address belongs to the A class. If it is 128--191, the address belongs to theB class. If the first octet is 192--223, the address belongs to the C class, otherwise it is an experimental or a multicast address. 1.3.3 Subnets The network addresses are managed by a central authority. Local administration manages the host addresses. Because network addresses are used in routing, the central authority is needed when the local network changes its structure. This might be quite a burden tothe central authority, but there is a solution developed for the Internet. A network may be split into several subnets, whichcan then be managed by independent agencies. The central network management doesn't have to know anything about subnets and hosts inthem. For instance Kone corporation has been assigned a B class network 138.249.0.0. This network has been divided to C classlike subnets, which are then given to the departments. The HAT department is given subnet 138.249.2.0, the HATMEC department subnet 138.249.5.0 and so on. 0________8________16______24_______ Address !!_________________________________1!138.249.!02.03001010!!111* *11001!!00000010!!00011110 ___________________________________ AND Netmask !!_________________________________1!255.255.255.!10111111!!11* *111111!!11111111!!00000000 _______________________________________________________________________ = Subnet !!_________________________________1!138.249.!02.0001010!!1111* *1001!!00000010!!00000000 Figure 1.2: Using netmask to find out subnetwork address. The subnet division is controlled by the netmask parameter. The actual subnetwork address is obtained by bit-wise AND between the netmask and the internet address. This subnet address is used in routing just like a normal net address. However, only hosts directly connected to the divided net have to know anything aboutnetmasks and subnets. 1.3.4 Broadcast Addresses There are two kind of broadcast addresses in the Internet. An obsolete form used in older BSD 4 versions used internet address with host part 0 ________________________________ 4Routers not taking part to such experiments normally discard all packets of this class. System Manual AmiTCP/IP Section 1.4 7 as the broadcast address. (The newer software usuallyconsiders addresses like those as network addresses.) Accordingthe the current Internet standard the broadcast addresses have the host part all 1's. ___________________________________________________________________ ! Interface ! ! Network ! Broadcast ! ! ! Netmask ! ! ! ! Address ! ! Address ! Address ! !________________!________________!_______________!________________! ! 10.14.123.2 !255.255.255.0 ! 10.14.123.0 ! 10.14.123.255 ! ! 130.244.5.4 !255.255.255.128 ! 130.244.5.0 ! 130.244.5.127 ! !_192.36.148.21_!255.255.255.0___!_192.36.148.0__!_192.36.148.255_!_ Table 1.2: Examples of netmasks, network addresses andbroadcast addresses. 1.4 Utilities Currently, only a few networking utilities are ported for the AmiTCP/IP. They are used to monitor and control network operation with AmiTCP/IP. There is a separate reference entry foreach network utility and daemon in the document file netutil.doc. This autodoc file isincluded in the appendix A, starting from page 111. 1.4.1 arp arp displays and modifies the internet to hardware address translation tables used by the Address Resolution Protocol. It isused if you are connected to a broadcast network, eg. Ethernet or Arcnet. You may examine, add, and delete ARP entries. Usually arp is used to find out hardware address of hosts. The hardware addresses are given as hexadecimal strings, each octet separated by a colon. Examples: 1.> arp -s puucee 8:0:9:32:f2:4c pub This command sets the hardware address for the host 'puucee' as '8:0:9:32:f2:4c'. 1.4.2 ifconfig ifconfig configures network interface parameters. Itassigns an internet address to a SANA-II network interface or sets interface parameters. ifconfig is normally used at the AmiTCP/IP startup. Examples: 1.> ifconfig lo/0 127.1 This command marks internal loopback device up, and attaches the internet address 127.0.0.1 to it. 8 Section 1.4 AmiTCP/IP System Manual 1.> ifconfig cslip.device/0 inet 193.102.4.144 193.102.4.129 This command starts the CSLIP driver, attaches an address 193.102.4.144 (our internet address) and a destination address 193.102.4.129 (the internet address of the host you are connecting) to it. 1.> ifconfig a2065.device/0 inet 193.124.100.66 + netmask 255.255.255.192 up -arp This command loads an ethernet driver for the Commodore A2065 Ethernet adapter unit 0, marks it UP, disables ARP protocol for it, attaches an inet address 193.124.100.66 to it and sets its netmask to 255.255.255.192. A bitwise logical AND of the netmask and the address for the interface forms the subnet address, in this case 193.124.100.66. All packets aimed to hosts with same subnet address (that is hosts 193.124.100.65--193.124.100.126) are routed to this interface. 1.4.3 letnet letnet is a simple TCP connection tool. With it you can connect to a TCP port at given host. Letnet reads data from standard input and sends it to the host. Likewise it receives data from the connection and writes it to the standard output. Letnet terminates upon shutdown of the socket or receiving SIGBREAKF_CTRL_C signal. Letnet does not handle telnet protocol. 1.4.4 netstat netstat shows network status. It symbolically displaysinformation of network data structures of the AmiTCP/IP. There are several standard AmigaDOS style options: By default displays all sockets that are not listening. ALL displays all sockets. STATUS displays values of several protocol-related variables. Example: 1.> netstat status Netstat is an ARexx script which uses the AMITCP port of the AmiTCP/IP to collect the information. See section2.5.1 (p. 18) for details about the ARexx commands supported by the AmiTCP/IP. 1.4.5 NapsaTerm NapsaTerm is a VT102 terminal emulator for logging remotely to Unix hosts with rlogin protocol. It is based on the NiftyTerm version 1.2 for Amiga by Chris Newman and William Todd. System Manual AmiTCP/IP Section 1.5 9 1.> run napsaterm -d net happi.hut.fi This command starts VT102 emulator with a rlogin connection to the host happi.hut.fi. 1.4.6 offline offline5 sends the S2_OFFLINE command to thegiven SANA-II device driver. This command is normally used to disconnect SANA-II device driver from the network adapter hardware. After this command the device driver does not accept any more read or write requests. Example: 1.> offline slip.device/0 This command puts the SLIP driver unit 0 offline, which frees then the serial port to other use. 1.4.7 online online sends the S2_ONLINE command to the given SANA-II device driver. The device driver restarts the network adapter hardware and accepts read and write request again. Example: 1.> online a2066.device/0 This command tries to start the Commodore ARCNET network adapter. 1.4.8 route route manipulates the routing tables. It is normally used at the AmiTCP/IP startup sequence to provide the default routing information in the routing tables. All needed routing information canbe provided with this command. Routes determine into which network IP packets are sent. Usually there is only need to set the default route toyour gateway and the route to the host itself through the loopback device. More route entries may be needed if your host is used as a gateway. 1.5 Errors and Logging There are two kinds of error reports AmiTCP/IP produces: Errors might be produced when a user process or a network supplies invalid data. These don't cause any problems to AmiTCP/IP. These events are logged6 to help the user to find out possible problems with his/her system. ________________________________ 5offline and online are compatible with the Commodore supplied SANA-II utilities with same names. However, they support the AmiTCP/IP naming convention. 6if logging is not disabled 10 Section 1.7 AmiTCP/IP System Manual Failures are more serious. These mean that AmiTCP/IP has entered to state where there is no way out. In Unix systems these cases lead to panic() and immediate restart. This is because in Unix systems networking software is integral part of the kernel and if something goes wrong, it usually means that the whole kernel is corrupted. This is not the case in Amiga and AmiTCP/IP, however. As AmiTCP/IP runs as a normal process, rest of the system can work even if networking fails. In Unix systems the syslogd takes care of the error reporting using an attached console. In AmigaOS there is no general failure reporting system, only User Requesters which are inadequate for non-interactive use. As logging could be used even while in interruptlevel, AmiTCP/IP can't write to log-files itself. This is why the actual logging is done by the NETTRACE process. It is started at AmiTCP/IP startup and can be configured through AMITCP ARexx port. ARexx commands can be found in section 2.5.1 (p. 18). 1.6 Troubleshooting This section is reserved for the frequently asked questions and answers to them. 1.7 Testing Utilities There are two testing utilities providedwith the AmiTCP/IP. The agnet7 controls the loopback pseudo device which simulates different networks. The qwriter simulates some typical application programs. They can be used together to test the integrity of the protocol stack. 1.7.1 Agnet SANA-II pseudo device driver agnet.device works as a network between its units. Packets from one unit are sent to another according given destination address. You can also arrange an unit-to-unit connection, if you want to simulate point-to-point devices. The loopback device provides nearly full SANA-II device driver functionality. It provides different hardware types, packet types and the variable hardware address width from0 to 128 bits. It collects all the required statistics. It does not provide the multicast functionality. A specialcommand file env:sana2/agnetn.config is used to configure and control the device. Configuration parameters may be specified by supplying its keyword and the wanted value. Any parameter may be left out. ________________________________ 7As Good NETwork as you like System Manual AmiTCP/IP Section 1.7 11 The configuration file parsing template is WIRE/K,MTU/N/K,MINTU/N/K,BPS/N/K,ADDR=ADDRESS/K, DELAY/N/K,DEV=DEVIATION/N/K,ERRORS/K/N,LOSS/K/N,DST=DSTUNIT/K/N.8 User configurable parameters are: WIRE hwiretypei is the hardware type which device driver will report. Other default parameters are set according to it. Default hardware type is Ethernet. With different wire types you can test for instance Ethernet specific features of AmiTCP/IP without killing the whole Ethernet segment of your network. ADDRESS hhardware addressi is the hardware addresses for the unit. Address is specified as a hexadecimal octet string. Octets are separated by colons. The length of the address depends of the hardware type. For example, 8:0:9:14:74:53 is a legal Ethernet hardware address. Alias: ADDR. DSTUNIT hunit numberi is the destination unit for a unit-to-unit connection. If this parameter is given, all packets sent to the unit are relayed to specified destination unit regardless of the packet destination address. MTU hnumber of octetsi is the maximum packet size that pseudo network will accept. Default value is 1500 octets, same as the MTU for the Ethernet. MINMTU hnumber of octetsi is the minimum packet size that pseudo network will accept. Smaller packets are padded to this minimum length. Default value depends on the hardware. It is for instance 46 octets for the Ethernet. BPS htransmission speedi is the bit speed which device driver will report to the user. DELAY hdelay timei specifies the delay of network in milliseconds. By default there is no delay. DEVIATION hstandard deviationi specifies delay variance in milliseconds. Packets are delayed randomly which means that packets may arrive in different order they were sent. Deviation without delay is meaningless. By default the variance is 0 ms and all packets have same delay. ERRORS hprobabilityi is theprobability of bit errors. This value can be in range [0..100 000 000], ERRORS/100 000 000 indicating probability of a single bit error. Error rate 100 000 000 means that all bits have random value. By default there are no errors (value 0). LOSS hprobabilityi defines the probability of the packet loss. This is a number in the range [0..1 000 000], LOSS/1 000 000 indicating probability. By default there is no packet loss. Note that value 1 000 000 means that all packets are lost. ________________________________ 8Alternative forms of keywordsare specified by using alt=keyword. Modifier /N specifies that the parameteris numeric. 12 Section 1.7 AmiTCP/IP System Manual ARexx Port for agnet.device The Arexx port is normally named as AGNET1. If thereis multiple instances of the agnet.device, the second instance has the port AGNET2 and so on. There iscurrently three different Arexx commands: UNIT Alias: U Some configuration parameters may be changed at run-time by Arexx commands. The Arexx configuration commands follow the same syntax as the configuration file. The user must specify the unit to configure by preceding the command with the keyword (UNIT, abbreviated as U) and a decimal unit number. For instance, the following is a legal Arexx configuration command: address AGNET1 unit 0 bps 2400 wire slip delay 100 QUERY Alias: Q The current configuration may be queried from the device by an ARexx command Q=QUERY. The command keyword is followed by an unit number and wanted configuration parameters. You can also give a keyword ALL, if you want all configuration parameters. For example, following command prints wiretype, delay, deviation and loss probability: options results address AGNET1 query 0 wire delay deviation loss say result EXIT Aliases: E, EXPUNGE The device may be expunged from the system memory by this Arexx command. The command fails, if there are some currently opened units. System Manual AmiTCP/IP Section 1.7 13 1.7.2 Qwriter qwriter9 works on the application layer. It is run as two distinct processes. A process acts as a server or a client. It creates one socket and sends and receives data through the socket. It is able to control data consistency and measures both latency times and throughput (if appropriate). Server part is started first in all tests. Server starts to listen to a port, and you can start the client. Tests are configurable, basic test types are described below. telnet simulates typical interactive use. In this test a TCP connection is created. The client end sends one character at a time and the server replies with four or more characters at a time. The most important measurement is the latency time between the sent character and the received echo. nfs simulates the data transfer of a network file system. In this test UDP messages are sent between processes. Both latency and the throughput are important measurements in this test. ftp is a simple TCP connection. In this test a TCP connection is created, then some data is transferred from one end to the another. In this test throughput is the key measurement. Command Line Options -s Act as a server (default). -c Act as a client. -t htypei Describes type of test: ftp, nfs or telnet. Type can be abbreviated to shortest unique length. Default is telnet. -n hcounti Describes how many times packets are sent back and forth. Applies to nfs and telnet. Default for hcounti is 1. -l hlengthi Describes length of data. Default is 1000 octets. Length has different meaning in different test contexts: ftp Length of the requested data for the client. Length parameter is meaningless for a ``ftp'' server. nfs The size of the packet to be sent to the other end. telnet The maximum length of data returned from the server. Actual length is random value between 4 and length octets. See also option ``-d''. This parameter is meaningless for a client. ________________________________ 9Quick WRITER 14 Section 1.7 AmiTCP/IP System Manual -d hn1,n2,: :,:nNiThis option has meaning for the telnet server and overrides the ``-l'' option. It specifies distibution of data lengths of replied packets to help better simulate typical interactive use where replies are usually short, but sometimes long (few kilobytes). Only k = 2i N first numbers have effect. Probability to have length less than nj (1 j k) is approximately Xk nj P (j) = P (j 1) + 1_ ___ k nl l=j (P (0) = 0) This can vary depending on random numeber generator and because of discret nature of computing. The largest length is nk. -b hsizei Size of the buffer tobe allocated for sends and/or replies. Default is 30 kilobytes. Amount of data to be send at once, if smaller than data to be sent. Maximum amount of data to be expected from the other end. -p hporti the server port number. The default is 1500. -h hhosti Name of the host to connect. Has no meaning for servers. The default is address ``127.0.0.1''. -q Calculate checksum and verify returned messages. Thisprovides way to check for integraty of transferred data. Checksum method is FCS as described in PPP RFC (1331). -T htimeouti Specifies timeout (in seconds) for retransmission. Only meaningful for nfs client. The default is 1.0 seconds. Chapter 2 Interfaces AmiTCP/IP provides Berkeley sockets compatible interface to the application programs. Networking applications can usethis interface to use TCP and UDP protocols, for example. AmiTCP/IPnetworking system uses SANA-II network devices. SANA-II is an Amiga standard network device driverinterface at the data link layer. Figure 2.1: Interfaces between different modules of the AmiTCP/IP internetworking system. There isalso a standard ARexx interface for logging, statistics and configuration in AmiTCP/IP. 2.1 AmiTCP/IP Processes AmiTCP/IP uses one protocol process. The protocol process starts listening specified SANA-II device drivers for incoming network frames 15 16 Section 2.3 AmiTCP/IP System Manual and sends timeout requests periodicallyto the timer device. Output to the network is usually done in the API callers context concurrently with the input processing. There isone other task called NETTRACE taking care of error reporting and the ARexx port of the AmiTCP/IP. Thecommands for this port are described later in the section 2.5.1. 2.2 Application Interface Application Interface is implemented asa standard Amiga shared library. Each task that opens the library (usingthe OpenLibrary() call) is given an unique data area (called a library base), which AmiTCP/IP uses it to store task specific information (see section 3.1.2 for more on this subject). Once the library is opened, applications cancall the standard socket functions such as socket(), connect(), bind(), listen(), accept(), recv() and send(). 2.3 SANA-II Interface AmiTCP/IP can use (hopefully) any SANA-II [SANA-II 1992 ] device. However, there may be problems with packet types and addressing. Many protocols may use the same hardware if each protocol uses unique packet type number. For instance, in the Ethernet theIP protocol have packet type 2048, the Xerox NS protocoluses the packet type 1536. The device driver directs packets to different protocols depending of their type. IP packet type varies in different hardware, forinstance ARCNET uses packet type 240 for IP1. SANA-II devices are required to follow the hardware type numbers assigned in the [Reynolds 1990 ]. There is only one hardware typewhich for instance all Ethernet drivers shoulduse. The SANA-II interface module uses the hardware type number todetermine packet types for each protocol. The hardware level addressing complicates the situation further. It is not possible to provide a general addressing scheme in hardware level. AmiTCP/IP can use a driver only if thereis some mapping from IP addresses to hardware addresses. SometimesSANA-II network driver uses an IP compatible addressing scheme, for instance SLIP or PPP drivers2 use an IP address asthe hardware address. Other solution is to use Address Resolution Protocol (ARP). With ARP AmiTCP/IP can map any IPaddress to the corresponding hardware address. For installing appropriate SANA-II device driver the manual of the device driver should be consulted. Note that if the device driver is not installed into the devs:networks directory, a full path must be specified when the driver is first referred to after the startup. ________________________________ 1There is an extension to ARCNET IP that is incompatible with old one. It uses packet type 212 for IP. 2At the hardware level these protocols do not use addresses at all. System Manual AmiTCP/IP Section 2.5 17 A networkdevice driver can be attached to the AmiTCP/IP with ifconfig command. This can be done manually or by the network startup script. 2.3.1 Interface ioctls The AmiTCP/IP provides an upward compatible ioctl interface to configure the network interfaces. Refer to the autodoc entry protocols/if for standard BSD ioctl interface (see appendix D.1.3, page 190). The extension for this interface is meant toconfigure hardware dependent parameters in an uniform way. The ARP interface have been modified to be slightly more generic. The length of the hardware address is now passed in the arp_ha address field. A new ioctl accesses the contents of thewhole ARP mapping cache. (In the BSD the static ARP table is accessedvia the /dev/kmem.) 2.4 Configuration Files The initial state of AmiTCP/IP is set bythe configuration files. The syntax differs from one configuration file to another. For each file format there is usual a corresponding ARexx command with the same syntax. For instance, configuration options, which are set in the file AmiTCP:db/AmiTCP.config, may be set withthe SET command by an ARexx script. The entries of the AmiTCP:db/netdb file can beadded manually with the ADD command. 2.5 ARexx Interface In Amiga environment Exec message portsare standard way to communicate between applications. Because of the ease of programming and the efficiency the ARexx programming language has become the standard in the Amiga and structure it uses for messagesis also standard. AmiTCP/IP provides ARexx port named AMITCP which can be used to both configure and gather information from networking. This is much moreelegant compared to the BSD Unix way to read directly from the kernel memory. The AMITCP port can be used to set and query various variables and statistic tables. Brief example of the usage of the port follows: /*c:rexx * * An example to query some informationform AmiTCP/IP */ address AMITCP options results /* get results back */ 'Q' TASKNAME say "Name of amitcp task is" result 'SET' TASKNAME "INET" 'QUERY' ICMP CHKSUM IP CHKSUM TCP CONNECT UDP CHKSUM TASKNAME /* Query count of ICMP, IP and UDP checksums and TCP connects */ 18 Section 2.5 AmiTCP/IP System Manual parse value result with icps_checksum ips_badsum tcps_connects udps_badsum task* *name /* Parse values from result. (Names of the variables are from * the stat-structures */ say "New name is" taskname say icps_checksum "bad ICMP checksums" say ips_badsum "bad IP header checksums" say tcps_connects "TCP connections established (including accepts)" say udps_badsum "bad UDP checksums" This example will produce output similar to following: Name of amitcp task is AmiTCP New name is INET 0 bad ICMP checksums 0 bad IP header checksums 2531 TCP connections established (including accepts) 0 bad UDP checksums 2.5.1 Commands This section summarizes the commands recognized by the ARexx port of the AmiTCP/IP. The command lines may containcomments, which are started by the semicolon. ADD hentryi This command adds entries to thenetwork database. Templates for the entries are: WITH hfile namei [PREFIX=hentry typei] Include the file hfile namei. Entry type for the file may be specified with an optional prefix, which may be any of the entry types listed in this list. The file will be searched first from the AmiTCP:db directory, so that the actual path may be omitted, if the file resides inthat directory. For exmaple, WITH hosts PREFIX=HOST includes the file hosts, which contains only host entries. The host keyword must not be present at the file itself. The WITH command is useful for including database files downloaded from Unix machines. H=HOST haddressi hnamei [aliases] Add a host entry to the network database. Either H or HOST can be used as the keyword. The haddressi is the internet address of the host, the hnamei is the official name and [aliases] is an optional list of alias names for the host. Example: H 128.214.6.100 nic.funet.fi nic N=NET hnamei haddressi [aliases] Add a net entry to the network database. Arguments are as above for the HOST. Example: System Manual AmiTCP/IP Section 2.5 19 N loopback-net 127 software-loopback-net S=SERVICE hnamei hporti/hprotocoli [aliases] Add a service entry to the network database. The hporti is the port number for the hprotocoli for which the server for the service will listen for the service requests. [aliases] is as above. Example: S daytime 13/tcp P=PROTOCOL hnamei hprotocol numberi [aliases] Add a protocol entry to the network database. Example: P tcp 6 NS=NAMESERVER haddressi Add a name server entry to the network database. The haddressi is the address of the name server in the internet dot-notation. The name servers are searched in the order specified in the database. Example: NS 130.233.224.1 ; santra.hut.fi Note that the symbolic name is after the ';' character,which marks the start of an end of line comment. DO=DOMAIN hdomain namei Add a domain name entry to the network database. The hdomain namei is the part following the first '.' in the official host name. The domain entries specify the domains from which a host name is searched. The search is done in the order of the entries added to the network database. Example: DOMAIN cs.hut.fi QUERY hvariable namei [: :]:Get the value of the variable. Many variables have a two-level hierarchical structure (especially for variables related to the statistics) in which both the name of the table and the name of the variable itself must be supplied. Values for many variables can be queried with one command by putting names of the variables in a row. RESET Reread the network database file AmiTCP:db/netdb. SET hvariable namei hvariable valuei [::]: Set the value of a variable. Name of the variable is given as with QUERY and the value is given after the name. Multiple variables can be set with one command by supplying name-variable pairs. Note that some variables are read-only and others writeable only during configuration. 2.5.2 Variables Here is a complete list of all configuration and network statistic variables. 20 Section 2.5 AmiTCP/IP System Manual WITH Include a file with multiple settings. (This pseudo variable is a extension to the SET command.) ICMP Variables related to Internet Message Control Protocol. Alias: IC ERROR Number ofcalls to icmp_error(). Alias: E SHORTOLD No error because old IP wastoo short. Alias: S ICMPOLD No error because oldwas ICMP. Alias: I CODE ICMP code out of range. Alias: CO TOOSHORT Packet too short. Alias: T CHKSUM Checksum error. Alias: CH LENGTH Data length larger than packet. Alias: L RESPONSES Number of responses. Alias: R ICMPHIST ICMP packet send and reception history. See page 24 for details on the output format. Alias: ICH IP Variables related to Internet Protocol. TOTAL Total number of packets. Alias: T CHKSUM Checksum error. Alias: CH TOOSHORT Packet too short. Alias: TOOSH TOOSMALL Not enough data. Alias: TOOSM HEADER IP header length less than data size. Alias: H LENGTH IP header length larger than packet. Alias: LE FRAGMENTS Packet fragments received. Alias: FS FDROP Fragmentsdropped (duplicates, out of space). Alias: FD FTIMEOUT Fragments timed out. Alias: FT FORWARD Packets forwarded. Alias: FO FWDCANT Packets received forunreachable destination. Alias: FW REDIRECTSENT Packets forwarded on same net. Alias: RED NOPROTO Unknown or unsupported protocol. Alias: N DELIVER Packets consumed here. Alias: D LOCALOUT Total IP packets generatedhere. Alias: LO ODROPPED Lost packets due to nobufs,etc. Alias: OD REASSEMBLED Total packets reassembled ok. Alias: REA FED Output packets fragmented ok. Alias: FE OFRAGMENTS Output fragments created. Alias: OF FCANT Don't fragment flag was set, etc. Alias: FC TCP Variables related to Transmission Control Protocol. Alias: T CATTEM Connections initiated. Alias: CA ACCEPTS Connections accepted. Alias: A System Manual AmiTCP/IP Section 2.5 21 CONNECT Connections established. Alias: CO DROPS Connections dropped. Alias: DR CDROPS Embryonic connections dropped. Alias: CD CLOSED Connections closed (incl. drops). Alias: CL SEGSTIMED Segments where we tried to get rtt. Alias: SE RTTUPDATE Times we succeed rtt. Alias: RTT DELACK Delayed acknowledgments sent. Alias: DE TIMEODROP Connection dropped in rxmt timeout. Alias: T REXMTT Retransmit timeouts. Alias: RE PERSIST Persist timeouts. Alias: P KATIMEO Keepalive timeouts. Alias: KAT KAPROBE Keepalive probes sent. Alias: KAP KADROPS Connections dropped in keepalive. Alias: KAD STOTAL Total packets sent. Alias: ST SPACK Data packets sent. Alias: SP SBYTE Data bytes sent. Alias: SB SREPACK Data packets retransmitted. Alias: SREP SREBYTE Data bytes retransmitted. Alias: SREB SACKS Ack-onlypackets sent. Alias: SA SWPROBE Window probes sent. Alias: SWP SURGENT Packets sent with URGonly. Alias: SU SWUPDATE Window update-only packetssent. Alias: SWU SCTRL Control (SYN_FIN_RST) packets sent. Alias: SC RTOTAL Total packets received. Alias: RTO RPACK Packets received in sequence. Alias: RPA RBYTE Bytes received in sequence. Alias: RB RCHKSUM Packets received withchecksum errors. Alias: RC ROFFSET Packets received withbad offset. Alias: ROF RPSHORT Packets received tooshort. Alias: RPS RDUPPACK Duplicate-only packets received. Alias: RDUPP RDUPBYTE Duplicate-only bytes received. Alias: RDUPB RPDUPDATA Packets with some duplicate data. Alias: RPDUPD RPDUPBYTE Dup. bytes in part-dup. packets. Alias: RPDUPB ROOPACK Out-of-order packetsreceived. Alias: ROOP ROOBYTE Out-of-order bytes received. Alias: ROOB RPLATE Packets with data after window. Alias: RPL RBLATE Bytes receivedafter window. Alias: RBL RAFTER Packets received after close. Alias: RAF RWPROBE Received window probepackets. Alias: RWP 22 Section 2.5 AmiTCP/IP System Manual RDUPACK Received duplicate acknowledgments. Alias: RDUPA RACKTOOM Received acknowledgments for unsent data. Alias: RACKT RACKPACK Received acknowledgment packets. Alias: RACKP RACKBYTE Bytes acknowledged by received acknowledgments. Alias: RACKB RWUPDATE Received window update packets. Alias: RWU UDP Variables related to User Datagram Protocol. Alias: U ITOTAL Total input packets. Alias: I HEADSHORT Packet shorter than header. Alias: H CHKSUM Checksum error. Alias: C LENGTH Data length larger than packet. Alias: L NOPORT No socket on port. Alias: N BCNOPORT No socket on port, arrivedas broadcast. Alias: B FULLSOC Not delivered, inputsocket full. Alias: F MISPCB Input packets missing pcb cache. Alias: M OTOTAL Total output packets. Alias: O CONNECTIONS Returns a list ofall TCP and UDP connections, including server (listening) sockets. See page 24 for the output format description. MBUF_STAT Memory buffer statistics. Alias: MBS MBUFS Total number of allocated memory buffers. Alias: M CLUSTERS Total number of allocated memory buffer clusters. Alias: CL CLFREE Number of memory buffer clusters free. Alias: CLF MDROPS Times failed tofind space. Alias: MD NWAITED Times waited for space. Alias: NW NDRAINED Times drained protocols forspace. Alias: ND TOTALMEMORYUSED Total amount of memory used for the mbufs. Alias: TMU MBUF_TYPE_STATS Returns type specific statistics of mbuf allocations. The last number is the total number of mbufs allocated. Alias: MBTS MBUF_CONF Memory buffer configuration. Alias: MBC INITIAL Number of mbuf chunksto allocate initially. Alias: I CHUNK Number ofmbufs to allocate at a time. Alias: CH CLCHUNK Number of clusters toallocate at a time. Alias: CL MAXMEM Maximum memoryto use (in kilobytes). Alias: MM CLUSTERSIZE Size of an mbuf cluster. Alias: CS System Manual AmiTCP/IP Section 2.5 23 LOG Logging system configuration. COUNT Number oflog messages to use. LEN Maximum length of a log message. TASKNAME Name of AmiTCP/IP task. NTHBASE Current AmiTCP/IP has nth bsdsocket.library base currently in memory. Alias: NTH DEBUGSANA Boolean to switch the SANA-II device interface debugging on and off3. Alias: DBSANA DEBUGICMP Boolean to switch the ICMP debugging on and off. Alias: DBICMP DEBUGIP Boolean telling whether IP should log debugging information. Alias: DBIP GATEWAY Boolean to switch gateway functionality on and off. Alias: GTW IPSENDREDIRECTS Boolean telling whether IP should send ICMP redirect messages. Alias: REDIR USENAMESERVER How to use name server. Possible values are: NO Do not use name server at all. Local database will be used instead. FIRST Query thename servers first and if that fails, use local database. SECOND First look up the local database, then, if that fails, query the name servers. Alias: USENS USELOOPBACK If true use the local loop device for local traffic. Alias: ULO TCP_SENDSPACE Default size of the sending socket buffer (TCP). Alias: TCPSND TCP_RECVSPACE Default size of the receiving socket buffer (TCP). Alias: TCPRCV CONSOLENAME Filename for thelog console. Alias: CON LOGFILENAME Filename for thelog file. Alias: LOGF ________________________________ 3See page 24 for description about boolean variable. 24 Section 2.5 AmiTCP/IP System Manual Boolean variables The variables documented as boolean accept their values in various formats. Boolean false may be given asNO4 , FALSE, OFF or 0. YES, TRUE, ON and 1 are considered as boolean true. The firstalternatives are used on output. CONNECTIONS output format CONNECTIONS query returns its result ina format which has space-separated fields, connection afterconnection (not sorted). Format is as follows: _____________________________________________________________________ !_Field_length_!___Value_type____!Description_______________________!_ !_______1_______!char_`t'_or_`u'_!t_for_TCP_connection,_u_for_UDP_!__ !_______4_______!__4-char_hex____!Receive_queue_length_____________!_ !_______4_______!__4-char_hex____!Send_queue_length________________!_ !_______8_______!__8-char_hex____!Local_address_____________________!_ !_______4_______!__4-char_hex____!Local_port_number________________!_ !_______8_______!__8-char_hex____!Foreign_address___________________!_ !_______4_______!__4-char_hex____!Foreign_port_number______________!_ !_______1_______!__1-char_hex____!State_of_connection______________!_ The hexadecimal values are zero padded from left to their full length. Last item presents the state of the TCPfinite state machine. Possible values for it are: ____________________________________________________ !_Value_!State_of_TCP_FSM________________________!__ !___0___!Closed___________________________________!_ !___1___!Listening_for_connection________________!__ !___2___!Active,_has_sent_SYN____________________!__ !___3___!Has_send_and_received_SYN______________!___ !___4___!Established______________________________!_ !___5___!Received_FIN,_waiting_forclose_________!___ !___6___!Has_been_closed,_sent_FIN______________!___ !___7___!Closed_exchanged_FIN;_awaiting_FIN_ACK_!___ !___8___!Had_FIN_and_close;_awaiting_FIN_ACK_____!__ !___9___!Has_been_closed,_FIN_is_acknowledged___!___ !___A___!Is_in_2*msl_quiet_wait_after_close______!__ ICMPHIST output format ICMPHIST query returns the ICMP historytable entries on one line separated by spaces. Outhistory is returned first beginning from the entry 0. Both tables contains 19 entries for differentICMP messages. Note that all message types are not in use. Message types are as follows:________________________ 4Upper case keywords are used here for clarity only. Lower case (or mixed case) keywords are accepted as well. System Manual AmiTCP/IP Section 2.5 25 ________________________________ !__0_e!cho_reply_______________!_ !__1_n!ot_used_________________!_ !__2_n!ot_used_________________!_ !__3_D!estination_unreachable_!_ !__4_P!acket_lost,_slow_down__!_ !__5_S!horter_route____________!_ !__6_n!ot_used_________________!_ !__7_n!ot_used_________________!_ !__8_E!cho_service_____________!_ !__9_n!ot_used_________________!_ !_10_!not_used_________________!_ !_11_!Time_exceeded____________!_ !_12_!IP_header_bad____________!_ !_13_!Timestamp_request________!_ !_14_!Timestamp_reply__________!_ !_15_!Information_request_____!_ !_16_!Information_reply________!_ !_17_!Address_mask_request____!_ !_18_!Address_mask_reply______!_ 26 Section 2.5 AmiTCP/IP System Manual Chapter 3 Programmer's Manual This chapter provides an in depth description of the AmiTCP/IP application programming interface. Following sectionsintroduce the socket model of communication (3.1) andthe bsdsocket.library function calls implementing the socket abstraction. Some useful supporting routines are described in section 3.2. The client/server model is introduced in section 3.3. Some more advanced topics are discussed in section 3.4. Section 3.5 summarizes the small differences between AmiTCP/IP and 4.3BSD socket APIs. The full function reference of the AmiTCP/IP API functions is in appendix Bstarting from page 128. The textin sections 3.1 -- 3.4 is based on the [Leffler et al 1991a ]. 3.1 Socket Concepts The basic building block for communication is the socket. A socket is an endpoint of communication to which a name may be bound. Each socket in use has a type and one or more associated processes. Sockets exist within communication domains. A communication domain is an abstraction introduced to bundle common properties of processes communicating through sockets. One such property is the scheme used to name sockets. Sockets normally exchange data only with socketsin the same domain1. The AmiTCP/IP system supports currently onlyone communication domain: the Internet domain, which is used by processes which communicate using the the DARPA standard communication protocols. The underlying communication facilities provided by the domains havea significant influence on the internal system implementation as well as the interface to socket facilities available to a user. 3.1.1 Socket Types Sockets are typed according to the communication properties visible to a user. Processes are presumed to communicate only between sockets of the same type, although there is nothing that prevents communication between ________________________________ 1It may be possible to cross domain boundaries, but only if some translation process is performed. 27 28 Section 3.1 AmiTCP/IP System Manual sockets of different types should the underlying communication protocols support this. Three types of sockets currently are available to a user. A stream socket provides for the bidirectional, reliable, sequenced, and unduplicated flow of data without recordboundaries. Aside from the bidirectionality of data flow, a pair ofconnected stream sockets provides an interface nearly identical to that of pipes.2 A datagram socket supports bidirectional flow of data which is not promised to be sequenced, reliable, or unduplicated. That is, a process receiving messages on a datagram socketmay find messages duplicated, and, possibly, in an order different from the order in which it was sent. An important characteristic of a datagram socket is that record boundaries in data are preserved. Datagram sockets closely model the facilities found in many contemporary packet switched networks such as the Ethernet. A raw socket provides users access to the underlying communication protocols which support socket abstractions. These sockets are normally datagram oriented, though their exact characteristics are dependent on the interface provided by the protocol. Raw sockets are not intended for the general user; they have been provided mainly for those interested in developing new communication protocols,or for gaining access to some of the more esoteric facilities of an existing protocol. The use of raw sockets is considered in section 3.4. Another potential socket type which has interesting properties is the reliably delivered message socket. The reliably delivered message socket has similar properties to a datagram socket, but with reliable delivery. There is currently no support for this type of socket, but a reliably delivered message protocol similar to Xerox's Packet Exchange Protocol (PEX) may be simulated at the user level. More information on this topic can be found in section 3.4. 3.1.2 Using The Socket Library As any other Amiga shared library the bsdsocket.library must be opened to be able to access the functions in the library. Thiscan be done with Exec's OpenLibrary() call. The call returns a librarybase pointer which is task specfic, which means that each separate task (or process) must open the library itself. This is because the AmiTCP/IPstores task specific information to the library basestructure. The library base pointer returned by the OpenLibrary() must be stored in to a variable accessable from the program (usually global) named SocketBase. Example of opening the library follows: #include ... struct Library *SocketBase = NULL; ... if ((SocketBase = OpenLibrary("bsdsocket.library", 2)) == NULL) - ________________________________ 2In the UNIX systems pipes havebeen implemented internally as simply a pair of connected stream sockets. System Manual AmiTCP/IP Section 3.1 29 /* couldnot open the library */ ... " else - /* SocketBase now points to socket base of this task */ ... " Note thatthe library version argument of the OpenLibrary() call is given as 2, which means that at least version 2 is needed. This is the minimum version which should be requested, since the version 1 is incompatible with the version 2 and up. If the application uses features defined for some specific version (and up), a later version number should be specified. After theapplication is done with sockets the library must be closed. This is done with CloseLibrary() as follows: if (SocketBase) - CloseLibrary(SocketBase); SocketBase = NULL; " Note thatif the application in question is multithreaded, each task (or process) need to open/close its ownlibrary base. The base opened by the net.lib may be used by the originaltask only! Many programs expect the error values of the socket calls to be placed in a global variable named errno. By default a sharedlibrary cannot know the address (nor size) of the applications variables, however. There are two remedies to this: 1. Use function Errno() to retrieve the error value, or 2. Tell the address and the size of the errno variable to the AmiTCP/IP by using the SetErrnoPtr() call. The latter method requires only one additional function call to the startup of the application, and is thusthe preferred method. The call may look like: #include #include ... SetErrnoPtr(&errno, sizeof(errno)); All thisis done automatically for the application if it is linked with the net.lib3. See section 3.1.3 for more information about the net.lib and about compiling and linking the applications. ________________________________ 3The net.lib is compiler dependent and is currently defined for SASC 6 only. The actual name of the library varies and depends on the compiler options used. 30 Section 3.1 AmiTCP/IP System Manual 3.1.3 Compiling and Linking The Applications AmiTCP/IP provides standard BSD Unix header files to be used by the applications. Normally they are installed to a directory which is assigned to a name NETINCLUDE: (see section 1.1). This means that you should add the NETINCLUDE: to the compilers search path for include files. The include files are decribed briefly in the following subsection: The NETINCLUDE Header Files bsdsocket.h This file includes compiler specific prototypes and inline functions for bsdsocket.library. Currently supported compilers are GCC and SAS C version 6. The prototypes for the library functions are automatically included by the include files when appropriate, i.e. when the prototypes where declared in the original BSD includes. Thus the bsdsocket.h is included by sys/socket.h, netdb.h and arpa/inet.h. For other compilers only C prototypes are included, so stub routines should be used to call the functions. errno.h Replacement for the errno.h included in the standard C-compiler headers. This includes the file sys/errno.h, which defines symbolic constants for the error values returned by socket library calls. This file is BSD compatible and may well replace file provided by the SAS/C 6. netdb.h Contains definitions and prototypes for the network database functions, such as the gethostbyname(). Standard BSD System Headers sys/errno.h Error code definitions for system functions. sys/ioctl.h Definitions for socket IO control. sys/param.h General machine independent parameter definitions. sys/socket.h Definitions related to sockets: types, address families, options and prototypes. sys/syslog.h Definations for system logging facilities. sys/time.h Definition of structure timeval. sys/types.h Common C type definitions and file descriptorset macros for select(). Internet Related Headers arpa/inet.h Inet library function prototypes (inet_addr() etc.). Included for compatibility and only includes other include files. netinet/in.h Protocol numbers, port conventions, inet address definitions. netinet/in_systm.h Some network byte order type definitions. netinet/ip.h IP packet header, packet options, timestamp. System Manual AmiTCP/IP Section 3.1 31 netinet/ip_icmp.h ICMP packet structure. netinet/ip_var.h Defines IP statistics, external IP packet header, reassemble queues structures. netinet/tcp.h Defines the TCP packet structure. netinet/udp.h Defines the UDP packet structure. Network Related Headers net/if.h Defines the interface for network adapter drivers. net/if_arp.h General protocol independent ARP structures. net/route.h Routing ioctl definitions. net/sana2errno.h Sana-II related error definitions. net/sana2tags.h Tag definitions for configuring the Sana-II software network interface. Inetd Support inetd.h Internet daemon interface definitions. inetdlib.h Internet daemon library definitions. Prototypes clib/socket_inlines.h Inline function definitions for those BSD socket API functions, which are not implemented strictly like originals by bsdsocket.library. clib/socket_protos.h bsdsocket.library function call prototypes. SAS/C Pragmas pragmas/socket_pragmas.h SAS/C pragma library calls for bsdsocket.library. SAS/C Proto -file proto/socket.h Include file normally included by the SAS/C programs. Defines the socket base variable and includes the files clib/socket_protos.h and pragmas/socket_pragmas.h. GCC Inline Functions inline/socket.h GCC inline functions for the bsdsocket.library functions. Function Description File fd/socket_lib.fd Standard fd-file which specifies in which registers the arguments to the bsdsocket.library functions are passed. This file can be used to obtain information needed to call the bsdsocket.library functions by the assembler programs. Sana-II Header Files devices/sana2.h Definitions for the Sana-II network device driver interface. 32 Section 3.1 AmiTCP/IP System Manual devices/sana2specialstats.h Special statistics definitions for the Sana-II. Miscellaneous charread.h Macro package to do buffered byte-by-byte reading from a socket. lineread.h Definitions for buffered line orientedreading from a socket. Linking With net.lib AmiTCP/IP distribution includes a link library named net.lib to be used by the applications. It is normally located in the directory which has an assigned name NETLIB:. The library contains compiler dependent code which makes the library itself compiler dependent. Currently only SASC version6 is supported4. net.lib features automatic initialization and termination functions which open and close the bsdsocket.library for the application. Using this feature it is possible to compile some typical BSD Unix socket based applications with AmiTCP/IP without anymodifications to the original source code. Note that this base may be used by the process starting the program, i.e. the one that executes themain(). This applies to the included utility functions which call the socket library, too. The library also defines new array of error names to be used by perror() library function. This is done because the error name array normally used by Amiga C compilers doesnot contain enough error entries, resulting perror() to print "Unknown error code" if some socket error is passed. Note that for perror() to work the error valuemust be placed into the global errno variable. This is accomplished by the SetErrnoPrt() call made in the automaticinitialization function. For the library functions to take effect, the library must be specified before the C compiler own libraries in the link command line. 3.1.4 Socket Creation To create a socket the socket() system call is used: s = socket(domain, type, protocol); This call requests that the system create a socket in the specified domain and of the specified type. A particular protocol may also be requested. If the protocol is left unspecified (a value of 0), the system will select an appropriate protocol from those protocols which comprise the communication domain and which may be used to support the requested socket type. The user is returned a descriptor (a small integer number) which may be used in later system calls which operate on sockets. The domain is specified as one of the manifest constants ________________________________ 4But since the source for the library is provided, it can be used with any C compiler. System Manual AmiTCP/IP Section 3.1 33 defined in the file sys/socket.h. For the Internet domain the constant is AF_INET5. The socket types are also defined in this file and one of SOCK_STREAM, SOCK_DGRAM or SOCK_RAW mustbe specified. To create a stream socket in the Internet domain the following call might be used: s = socket(AF_INET, SOCK_STREAM, 0); This call would result in a stream socket being created with the TCP protocol providing the underlying communication support. To create a datagram socket the call might be: s = socket(AF_INET, SOCK_DGRAM, 0); The default protocol (used when the protocol argument to the socket() call is 0) should be correct for most every situation. However, it is possible to specify a protocol other than the default; this will be covered in section 3.4. There areseveral reasons a socket() call may fail. Aside from the rare occurrence of lack of memory (ENOBUFS), a socket request may fail due to a request for an unknown protocol(EPROTONOSUPPORT), or a request for a type of socket for which there isno supporting protocol (EPROTOTYPE). 3.1.5 Binding Local Names A socket is created without a name. Until a name is bound to a socket, processes have no way to reference it and, consequently, no messages may be received on it. Communicating processes are bound by an association. In the Internet domain, an association is composed of local and foreign addresses, and local and foreign ports,In most domains, associations must be unique. In the Internet domain there may neverbe duplicate tuples. The bind() system call allows a process to specify half of an association, , while the connect() and accept() calls are used to complete a socket's association. In the Internet domain, binding names to sockets can be fairly complex. Fortunately, it is usually not necessaryto specifically bind an address and port number to a socket, because theconnect() and send() calls will automatically bind an appropriate address if they are used with an unbound socket. The bind() system call is used as follows: bind(s, name, namelen); The bound name is a variable length bytestring which is interpreted by the supporting protocol(s). Its interpretation may vary from communication domain to communication domain (this is one of the properties which comprise the domain). As mentioned, in the Internet domain names contain an Internet addressand port number. In binding an Internet address things are a little complicated: ________________________________ 5The manifest constants are named AF _whatever as they indicate the ``address format'' to use in interpreting names. 34 Section 3.1 AmiTCP/IP System Manual #include #include ... struct sockaddr_in sin; ... bind(s, (struct sockaddr *) &sin, sizeof (sin)); The selection of what to place in the address sin requires some discussion. We will come back to the problem of formulating Internet addresses in section 3.2 when the library routines used in name resolution are discussed. 3.1.6 Connection Establishment Connection establishment is asymmetric,with one process a ``client'' and the other a ``server''. The server, when willing to offer its advertised services, binds a socket to a well--known address associated with the service and then passively ``listens'' on its socket. It is then possible for an unrelated process to rendezvous with the server. The client requests services from the serverby initiating a ``connection'' to the server's socket. On the client side the connect() call is used to initiate a connection. Using the Internet domain, thismight apper as: struct sockaddr_in server; ... connect(s, (struct sockaddr *)&server, sizeof (server)); where server in the example above would contain Internet address and port number of the server to which the client process wishes to speak. If the client process's socket is unbound at the time of the connect call, the system will automatically select and bind a name to the socket if necessary. This is the usual way that local addresses are bound to a socket. An erroris returned if the connection was unsuccessful (any name automatically bound by the system, however, remains). Otherwise, the socket is associated with the server anddata transfer may begin. Some of the more common errors returned whena connection attempt fails are: ETIMEDOUT After failing to establish a connection for a period of time, the system decided there was no point in retrying the connection attempt any more. This usually occurs because the destination host is down, or because problems in the network resulted in transmissions being lost. ECONNREFUSED The host refusedservice for some reason. This is usually due to a server process not being present at the requested name. ENETDOWN or EHOSTDOWN These operational errors are returned based on status information delivered to the client host by the underlying communication services. ENETUNREACH or EHOSTUNREACH These operational errors can occur either because the network or host is unknown (no route to the network or System Manual AmiTCP/IP Section 3.1 35 host is present), or because of status information returned by intermediate gateways or switching nodes. Many times the status returned is not sufficient to distinguish a network being down from a host being down, in which case the system indicates the entire network is unreachable. For the server to receive a client's connection it must perform two steps after binding its socket. The first is to indicate a willingness to listen for incoming connection requests: listen(s, 5); The second parameter to the listen() call specifies the maximum number of outstanding connections which may be queued awaiting acceptance by the server process; this number may be limited by the system. Should a connection be requested while the queueis full, the connection will not be refused, but rather the individual messages which comprise the request will be ignored. This gives a harried server time to make room in its pending connection queue while the client retries the connection request. Had the connection been returned with the ECONNREFUSED error, the client would be unable to tell if the server was up or not. As it is now it is still possible to get the ETIMEDOUT error back, though this is unlikely. The backlog figure supplied with the listen call is currently limited by the system to a maximum of 5 pending connections on any one queue. This avoids the problem of processes hogging systemresources by setting an infinite backlog, then ignoring all connection requests. With a socket marked as listening, a server may accept a connection: struct sockaddr_in from; ... fromlen = sizeof (from); newsock = accept(s, (struct sockaddr *)&from, &fromlen); A new descriptor is returned on receiptof a connection (along with a new socket). If the server wishes to find out who its client is, it may supply a buffer for the client socket'sname. The value--result parameter fromlen is initialized by theserver to indicate how much space is associated with from, then modified on return to reflect the true size of the name. If the client's name is not of interest,the second parameter may be a NULL pointer. accept()normally blocks. That is, accept() will not return until a connection is available or the system call is interrupted by a signal6 to the process. Further, there is no way for a process toindicate it will accept connections from only a specificindividual, or individuals. It is up to the user process to consider who the connection is from and close down the connection if it does notwish to speak to the process. If the server process wants to accept connections on more than one socket, or wants to avoid blocking on the accept call, there are alternatives; they will be considered insection 3.4. ________________________________ 6By default, the CTRL-C signalinterrupts the system calls, but the application may change this, however. 36 Section 3.1 AmiTCP/IP System Manual 3.1.7 Data Transfer With a connection established, data maybegin to flow. To send and receive data there are a number of possible calls. With the peer entity at each end of a connection anchored, auser can send or receive a message without specifying the peer. The calls send()and recv() may be used: send(s, buf, sizeof (buf), flags); recv(s, buf, sizeof (buf), flags); While send() and recv() are virtually identical to the standard I/O routines, the extra flags argument is important. Theflags, defined in sys/socket.h, may be specified as a non--zero value if one or more of the following is required: MSG_OOB Send/receive out of band data. MSG_PEEK Lookat data without reading. MSG_DONTROUTESend data without routing packets. Out of band data is a notion specific to stream sockets, and one which we will not immediately consider. The option to have data sent without routing applied to the outgoing packetsis currently used only by the routing table management process, and isunlikely to be of interest to the casual user. The ability to preview data is, however, of interest. When MSG_PEEK is specified with a recv() call, any data present is returned to the user, but treated as still ``unread''. That is, the next recv() call applied to the socket will return the data previously previewed. 3.1.8 Discarding Sockets Once a socket is no longer of interest,it may be discarded by applying a CloseSocket() to the descriptor, CloseSocket(s); If data is associated with a socket which promises reliable delivery (e.g. a stream socket) when a close takes place, the system will continue to attempt to transfer the data. However, after a fairly long period of time, if the data is still undelivered, it will be discarded. Should a user have no use for any pending data, it may perform a shutdown() on the socket prior to closing it. This call is of the form: shutdown(s, how); where how is 0 if the user is no longerinterested in reading data, 1 if no more data will be sent, or 2 if no data is to be sent or received. System Manual AmiTCP/IP Section 3.1 37 3.1.9 Connectionless Sockets To this point we have been concerned mostly with sockets which follow a connection oriented model. However, there is also support for connectionless interactions typical of the datagram facilities found in contemporary packet switched networks. A datagram socket provides a symmetric interface to data exchange. While processesare still likely to be client and server, there is no requirement for connection establishment. Instead, each message includes the destination address. Datagramsockets are created as before. If a particular local address is needed, the bind operation must precede the first data transmission. Otherwise, the system will set the localaddress and/or port when data is first sent. To send data, the sendto() call is used, sendto(s, buf, buflen, flags, (struct sockaddr *)&to, tolen); The s, buf, buflen, and flags parametersare used as before. The to and tolen values are used to indicate the address of the intended recipient of the message. When using an unreliable datagram interface, it is unlikely that any errors will be reported to the sender. When information is present locally to recognize a message that can not be delivered (for instance when a network is unreachable), the call will return -1 and the global value errno will contain an error number (See section 3.1.2 for discussion about errno). To receive messages on an unconnected datagram socket, the recvfrom() call is provided: recvfrom(s, buf, buflen, flags, (struct sockaddr *)&from, &fromlen); Once again, the fromlen parameter is handled in a value--result fashion, initially containing the size of the from buffer, and modified on return to indicate the actual size of the address from which the datagram was received. In addition to the two calls mentioned above, datagram sockets may also use the connect() call to associate a socket with a specific destination address. In this case, any data sent on the socket will automatically be addressed to the connected peer, and only data received from that peer will be delivered to the user. Only one connected address is permitted for each socket at one time; a second connect() will change the destination address, and a connect() toa null address (family AF_UNSPEC) will disconnect. Connect requests on datagram socketsreturn immediately, as this simply results in the system recording the peer's address (as compared to a stream socket,where a connect request initiates establishment of an end to endconnection). accept() and listen() are not used with datagram sockets. While a datagram socket is connected, errors from recent send() calls may be returned asynchronously. These errors may be reported on subsequent operations on the socket, ora special socket option used with getsockopt(), SO_ERROR,may be used to interrogate the error status. A select() for reading or writing will return true when an error indication has been received. The next operation will return theerror, and the error status is cleared. Other of the less important details of datagram sockets are described in section 3.4. 38 Section 3.1 AmiTCP/IP System Manual 3.1.10 Input/Output Multiplexing One last facility often used in developing applications is the ability to multiplex i/o requests among multiple sockets. This is done using the select() call. The select() call provided by AmiTCP/IPis actually a compile time inline function (or normalstub with compilers without inline facility) which calls the WaitSelect(). The WaitSelect() call is similar to the normal select() call, buthas one extra argument specifying a pointer to a signal mask for the signals which should break the selection (in addition to the timeouts and the break signal). This makes possible to use WaitSelect() instead of normal Wait() as a driver for the applications event loop. If the pointer is given as NULL the functionality is as with BSD select(). The inline (orstub) function for select* *() actually just calls the WaitSelect() with last argument as NULL. Here is abrief example of the usage of the WaitSelect(): #include #include ... fd_set readmask, writemask, exceptmask; struct timeval timeout; ULONG signalmask; ... WaitSelect(nfds, &readmask, &writemask, &exceptmask, &timeout, &signalmask); WaitSelect() takes as arguments pointersto three sets, one for the set of file descriptors for which the callerwishes to be able to read data on, one for those descriptors to which data is to be written, and one for which exceptional conditions are pending; out-of-band data is the only exceptional condition currently implemented. If the user is not interested in certain conditions (i.e.,read, write, or exceptions), the corresponding argument to the select() should be a NULL pointer. Each setis actually a structure containing an array of long integer bit masks; the size of the array is setby the definition FD_SETSIZE. The array is long enough to hold one bit foreach of FD_SETSIZE file descriptors. The macros FD_SET(fd, &mask) and FD_CLR(fd, &mask) have been provided for adding and removing file descriptorfd in the set mask. The set should be zeroed before use, and the macro FD_ZERO(&mask) has been provided to clear the set mask. The parameter nfds inthe select() call specifies the range of file descriptors(i.e. one plusthe value of the largest descriptor) to be examined in aset. A timeoutvalue may be specified if the selection is not to last more than a predetermined period of time. If the fields intimeout are set to 0, the selection takes the form of a poll, returning immediately. If the last parameter is a NULL pointer, the selection will block indefinitely7. ________________________________ 7To be more specific, a returntakes place only when a descriptor is selectable, or when a signal is receivedby the caller, interrupting the system call. System Manual AmiTCP/IP Section 3.1 39 The lastargument is a pointer to the mask specifying signals for which the WaitSelect() should break. WaitSelect() normally returns the number of file descriptors selected; if the WaitSelect() call returns due to the timeout expiring, then the value 0 is returned. If the WaitSelect() terminates because of an error or interruption, a -1 is returned with the error number in errno, and with the filedescriptor masks unchanged. The signal mask is altered on return to holdthe bits for the signals which caused the break. Assuminga successful return, the three sets will indicate which file descriptors are ready to be read from, written to, or have exceptional conditions pending. The status of a file descriptor ina select mask may be tested with the FD_ISSET(fd, &mask) macro, which returns a non-zero value if fd is a member of the set mask,and 0 if it is not. To determine if there are connections waiting on a socket to be used with an accept() call, select() can be used, followed by a FD_ISSET(fd, &mask) macro to check for read readiness on the appropriate socket. If FD_ISSET() returns a non-zero value, indicating permission to read, then a connection is pending on the socket. As an example, to read data from two sockets, s1 and s2 as it is available from each and with a one--second timeout, the following code might be used: #include #include #include ... fd_set read_template; struct timeval wait; int nb; int s1,s2; int maxfd; ... maxfd = s1 > s2 ? s1 : s2; for (;;) - wait.tv_sec = 1; /* onesecond */ wait.tv_usec = 0; FD_ZERO(&read_template); FD_SET(s1, &read_template); FD_SET(s2, &read_template); nb = select(maxfd, &read_template, NULL, NULL, &wait); if (nb <=0) - /* An error occurred during the select, or the select timed out. */ " if (FD_ISSET(s1, &read_template)) - /* Socket #1 is ready to be readfrom. */ " if (FD_ISSET(s2, &read_template)) - /* Socket #2 is ready to be readfrom. */ 40 Section 3.2 AmiTCP/IP System Manual " " Note theusage of the select(), which calls WaitSelect() with NULL signal mask pointer. In 4.2BSD, the arguments to select() were pointers to integers instead of pointers to fd_sets. This type ofcall will still work as long as the number of file descriptors being examined is less than the number of bits in an integer; however, the methods illustrated above should be used in all current programs. select()provides a synchronous multiplexing scheme. Asynchronous notification of output completion, inputavailability, and exceptional conditions is possible through use of the SigIO and SigURG signals described in section 3.4. 3.2 Network Library Routines The discussion in section 3.1 indicatedthe possible need to locate and construct network addresses when using the interprocess communication facilities in a distributed environment. To aid in this task a number of routines have been added to the Amiga shared socket library. In this section we will consider the routines provided to manipulate network addresses. Locatinga service on a remote host requires many levels of mapping before client and server may communicate. A service is assigned a name which is intended for human consumption;e.g. ``the login server on host monet''. This name, and the name of the peer host, must then be translated into network addresses whichare not necessarily suitable for human consumption. Finally, the address must then usedin locating a physical location and route to the service. The specifics of these three mappings are likely to vary between network architectures. For instance, it is desirable for a network to not require hosts to be named in such a way that their physical location is known by the client host. Instead, underlying services in the network may discover the actual location of the host at the time a client host wishes tocommunicate. This ability to have hosts named in a location independent manner may induce overhead in connection establishment, as a discovery process must take place, but allows a host to be physically mobile without requiring it to notify its clientele of its current location. Standardroutines are provided for: mapping host names to network addresses, network names to network numbers, protocol names to protocol numbers, and service names to port numbers and the appropriate protocol to use in communicating with the serverprocess. The file netdb.h must be included when using any of these routines. 3.2.1 Host Names An Internet host name to address mappingis represented by the hostent structure: System Manual AmiTCP/IP Section 3.2 41 struct hostent - char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type (e.g., AF_INET) */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses, nullterminated */ "; #define h_addr h_addr_list[0] /* first address, network byte order */ The routine gethostbyname() takes an Internet host name and returns a hostent structure, while the routine gethostbyaddr() maps Internet host addresses into a hostent structure. The official name of the host and its public aliases are returned by these routines, along with the address type (family) and a null terminated list of variable length addresses. This list of addresses is required because it is possible for a host to have many addresses, all having the same name. The h_addr definition is provided for backward compatibility, and is defined to be thefirst address in the list of addresses in the hostent structure. The database for these calls is provided either by the configuration file or by use of a name server. Because of the differences in these databases and their access protocols, the information returned may differ. When using the host table version of gethostbyname(), only one address will be returned, but all listedaliases will be included. The name server version may return alternateaddresses, but will not provide any aliases other than one given as argument. 3.2.2 Network Names As for host names, routines for mappingnetwork names to numbers, and back, are provided. These routines return a netent structure: /* * Assumption here is that a network number * fits in 32 bits -- probably a poor one. */ struct netent - char *n_name; /* official name of net */ char **n_aliases; /* alias list */ int n_addrtype; /* net address type */ int n_net; /* networknumber, host byte order */ "; The routines getnetbyname(), andgetnetbynumber() are the network counterparts to the host routines described above. The routines uses data read from AmiTCP/IP configuration file. 3.2.3 Protocol Names For protocols, the protoent structure defines the protocol--name mapping used with the routines getprotobyname()and getprotobynumber(): 42 Section 3.2 AmiTCP/IP System Manual struct protoent - char *p_name; /* official protocol name */ char **p_aliases; /* alias list */ int p_proto; /* protocol number */ "; 3.2.4 Service Names Information regarding services is a bitmore complicated. A service is expected to reside at a specific ``port'' and employ a particular communication protocol. This view is consistent with the Internet domain, but inconsistent with other network architectures. Further, a service may reside on multiple ports. If this occurs,the higher level library routines will have to be bypassed or extended. A service mapping is described by the servent structure: struct servent - char *s_name; /* official service name */ char **s_aliases; /* alias list */ int s_port; /*port number, network byte order */ char *s_proto; /* protocol to use */ "; The routine getservbyname() maps service names to a servent structure by specifying a service name and, optionally, a qualifying protocol. Thus the call sp = getservbyname("telnet", NULL); returns the service specification for atelnet server using any protocol, while the call sp = getservbyname("telnet", "tcp"); returns only that telnet server which uses the TCP protocol. The routine getservbyport() is also provided. The getservbyport()routine has an interface similar to that provided by getservbyname(); an optional protocol name may be specified to qualify lookups. 3.2.5 Miscellaneous With the support routines described above, an Internet application program should rarely have to deal directly with addresses. This allows services to be developed as much as possible in a network independent fashion. It is clear, however, that purging all network dependencies is very difficult. So long as the user is required to supply network addresses when naming services and sockets there will always some network dependency in a program. For example, the normal codeincluded in client programs, such as the remote login program, is as follows: System Manual AmiTCP/IP Section 3.2 43 Remote Login Client Code #include #include #include #include #include ... int main(int argc, char *argv[]) - struct sockaddr_in server; struct servent *sp; struct hostent *hp; int s; ... sp = getservbyname("login","tcp"); if (sp == NULL) - fprintf(stderr, "rlogin: tcp/login: unknown service"n"); exit(1); " hp = gethostbyname(argv[1]); if (hp == NULL) - fprintf(stderr, "rlogin: %s: unknown host"n",argv[1]); exit(2); " bzero((char *)&server, sizeof (server)); server.sin_port = sp->s_port; bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); server.sin_family = hp->h_addrtype; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) - perror("rlogin: socket"); exit(3); " ... /* Connect does the bind()for us */ if (connect(s, (struct sockaddr *)&server, sizeof (server)) < 0) - perror("rlogin: connect"); exit(5); " ... " (This example will be considered in more detail in section 3.3.) If we wanted to make the remote login program independent of the Internet protocols and addressing schemewe would be forced to add a layer of routines which masked the network dependent aspects from the mainstream login code. For the current facilities available in the system this does not appear to be worthwhile. Aside from the address-related data base routines, there are several other routines available in the run-timelibrary which are of interest to 44 Section 3.3 AmiTCP/IP System Manual users. These are intended mostly to simplify manipulation of names and addresses. The routines for manipulating variable length byte strings and handling byte swapping of network addresses and values are summarized below:8. bcmp(s1, s2, n) Compare byte-strings; 0 if same, not 0 otherwise. bcopy(s1, s2, n) Copy n bytes from s1 to s2. bzero(base, n) Zero-fill n bytes starting at base. htonl(val) Convert 32-bit quantity from host to network byte order. htons(val) Convert 16-bit quantity from host to network byte order. ntohl(val) Convert 32-bit quantity from network to host byte order. ntohs(val) Convert 16-bit quantity from network to host byte order. The byteswapping routines are provided because the operating system expects addresses to be supplied in network order. Onsome architectures, such as the VAX, host byte ordering is different than network byte ordering. Consequently, programs are sometimes required to byte swap quantities. The library routines which return network addresses provide them in network orderso that they may simply be copied into the structures provided to the system. This implies users should encounter the byte swapping problem onlywhen interpreting network addresses. For example, if an Internet port is to be printed out the following code would be required: printf("port number %d"n", ntohs(sp->s_port)); On machines where unneeded (as on Amiga)these routines are defined as null macros. 3.3 Client/Server Model The most commonly used paradigm in constructing distributed applications is the client/server model. In this scheme client applications request services from a server process. This implies an asymmetry in establishing communication between the client and server which has been ________________________________ 8The byte string functions areprovided by the C-compiler. The byte order functions are provided as preprocessor macros. System Manual AmiTCP/IP Section 3.3 45 examined in section 3.1. In this section we will lookmore closely at the interactions between client and server, and consider some of the problems in developing client and serverapplications. The client and server require a well known set of conventions before service may be rendered (and accepted). This set of conventions comprises a protocol which must be implemented at both ends of a connection. Depending on the situation, the protocol may be symmetric or asymmetric. In a symmetric protocol, either side may play the master or slave roles. In an asymmetric protocol, one side is immutably recognized as the master, with the other as the slave. An example of a symmetric protocol is the TELNET protocol used inthe Internet for remote terminal emulation. An example of an asymmetric protocol is theInternet file transfer protocol, FTP. No matter whether the specific protocol used in obtaining a service is symmetric or asymmetric, when accessing a service there is a ``client process'' and a ``server process''. Wewill first consider the properties of server processes, then client processes. A serverprocess normally listens at a well known address for service requests. That is, the server process remains dormantuntil a connection is requested by a client's connection tothe server's address. At such a time the server process ``wakes up'' andservices the client, performing whatever appropriate actions the clientrequests of it. Alternative schemes which use a service server may be used to eliminate a flock of server processes clogging thesystem while remaining dormant most of the time. For Internet servers in 4.3BSD, thisscheme has been implemented via inetd, the so called ``internet super-server.'' Inetd listens at a variety of ports, determined at start-up by reading a configuration file. When a connection is requested toa port on which inetd is listening, inetd executes the appropriate server program to handle the client. Inetd will be described in more detail in section 3.4. 3.3.1 Servers In 4.3BSD most servers are accessed at well known Internet addresses or UNIX domain names. For example, the remote login server's main loop is of the form shown below (AmiTCP/IP way): main(int argc, char *argv) - int f; struct sockaddr_in from; struct servent *sp; sp = getservbyname("login", "tcp"); if (sp ==NULL) - fprintf(stderr, "rlogind: tcp/login: unknown service"n"); exit(1); " ... sin.sin_port = sp->s_port; /* Restricted port */ ... 46 Section 3.3 AmiTCP/IP System Manual f = socket(AF_INET, SOCK_STREAM, 0); ... if (bind(f, (struct sockaddr *) &sin, sizeof (sin)) < 0) - ... " ... listen(f, 5); for (;;)- int g, len = sizeof (from); g = accept(f, (struct sockaddr *)&from, &len); if (g < 0) - if (errno != EINTR) syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]); continue; " /* * AmiTCP code follows... */ id = ReleaseSocket(g, UNIQUE_ID); startit(id, &from); " " The firststep taken by the server is look up its service definition: sp = getservbyname("login", "tcp"); if (sp == NULL) - fprintf(stderr, "rlogind: tcp/login: unknown service"n"); exit(1); " The result of the getservbyname call isused in later portions of the code to define the Internet port at which it listens for service requests (indicated by a connection). Once a server has established a pristine environment, it creates a socket and begins accepting service requests. The bind() call is required to insure the server listens atits expected location. The mainbody of the loop is fairly simple: for (;;) - int g, len = sizeof (from); g = accept(f, (struct sockaddr *)&from, &len); if (g < 0) - if (errno != EINTR) syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]); continue; " /* * AmiTCP code follows... */ id = ReleaseSocket(g, UNIQUE_ID); startit(id, &from); " System Manual AmiTCP/IP Section 3.3 47 An accept() call blocks the server until a client requests service. This call could return a failure statusif the call is interrupted by a signal such as CTRL-C (to be discussed in section 3.4). Therefore, the return value from accept() is checked toinsure a connection has actually been established. With a connection in hand, servers using AmiTCP/IP socket library, this new socket is released to an external list inside AmiTCP/IP process via ReleaseSocket() call. ReleaseSocket() returns an id (unique if requested). startit() starts a new AmigaOS task and informs the id for it. This new task then uses ObtainSocket() with id asargument to receive the socket. The address of the client is alsohandled the new task because it requires it in authenticating clients. 3.3.2 Clients The client side of the remote login service was shown earlier in section 3.2. One can see the separate, asymmetric roles of theclient and server clearly in the code. The server is a passive entity, listening for client connections, while the client process is an active entity, initiating a connection when invoked. Let us consider more closely the steps taken by the client remote login process. As in the server process, the first step is to locate the service definition for a remote login: sp = getservbyname("login", "tcp"); if (sp == NULL) - fprintf(stderr, "rlogin: tcp/login: unknown service"n"); exit(1); " Next thedestination host is looked up with a gethostbyname() call: hp = gethostbyname(argv[1]); if (hp == NULL) - fprintf(stderr, "rlogin: %s: unknown host"n", argv[1]); exit(2); " With this accomplished, all that is required is to establish a connection to the server at the requested host andstart up the remote login protocol. The address buffer is filled in with the Internet address and rlogin port number of the foreign host. bzero((char *)&server, sizeof (server)); server.sin_port = sp->s_port; bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length); server.sin_family = hp->h_addrtype; A socket is created, and a connection initiated. Notethat connect() implicitly performs a bind() call, because s is unbound. s = socket(hp->h_addrtype, SOCK_STREAM, 0); if (s < 0) - 48 Section 3.3 AmiTCP/IP System Manual perror("rlogin: socket"); exit(3); " ... if (connect(s, (struct sockaddr *) &server, sizeof (server)) < 0) - perror("rlogin: connect"); exit(4); " The details of the remote login protocolwill not be considered here. 3.3.3 Connectionless Servers While connection-based services are thenorm, some services are based on the use of datagram sockets. One, in particular, is the ``rwho'' service which provides users with status information for hosts connected to a local area network. This service, while predicated onthe ability to broadcast information to all hosts connected to a particular network, is of interest as an example usage of datagram sockets. A user onany machine running the rwho server may find out the current status of a machine with the ruptime program. The output generated is illustrated below. Ruptime Output arpa up 9:45, 5 users, load 1.15, 1.39, 1.31 cad up 2+12:04, 8 users, load 4.67, 5.13, 4.59 calder up 10:10, 0 users,load 0.27, 0.15, 0.14 dali up 2+06:28, 9 users, load 1.04, 1.20, 1.65 degas up 25+09:48, 0 users, load 1.49, 1.43, 1.41 ear up 5+00:05, 0 users, load 1.51, 1.54, 1.56 ernie down 0:24 esvax down 17:04 ingres down 0:26 kim up 3+09:16, 8 users, load 2.03, 2.46, 3.11 matisse up 3+06:18, 0 users, load 0.03, 0.03, 0.05 medea up 3+09:39, 2 users,load 0.35, 0.37, 0.50 merlin down 19+15:37 miro up 1+07:20, 7 users, load 4.59, 3.28, 2.12 monet up 1+00:43, 2 users,load 0.22, 0.09, 0.07 oz down 16:09 statvax up 2+15:57, 3 users, load 1.52, 1.81, 1.86 ucbvax up 9:34, 2 users, load 6.08, 5.16, 3.28 Status information for each host is periodically broadcast by rwho server processes on each machine. The same server process also receives the status information and uses it to update a database. This database is then interpreted to generate the status information for each host. Servers operate autonomously, coupled only by the local network and its broadcast capabilities. Note thatthe use of broadcast for such a task is fairly inefficient, as all hosts must process each message,whether or not using an rwho System Manual AmiTCP/IP Section 3.3 49 server. Unless such a service is sufficiently universal and is frequently used, the expense of periodicbroadcasts outweighs the simplicity. The rwhoserver, in a simplified form, is pictured next9: BYTE alrmsig; main() - long on; fd_set readfds; ... sp = getservbyname("who", "udp"); sin.sin_port = sp->s_port; net = getnetbyname("localnet"); sin.sin_addr = inet_makeaddr(INADDR_ANY, net); ... s = socket(AF_INET, SOCK_DGRAM, 0); ... on = 1; if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) - syslog(LOG_ERR, "rwhod: setsockopt SO_BROADCAST: %s", strerror(errno)); exit(1); " bind(s, (struct sockaddr *) &sin, sizeof (sin)); ... alrmsig =AllocSignal(-1); onalrm();/* activate and handle periodic alarm system */ FD_ZERO(&readfds); FD_SET(s, &readfds); for (;;)- struct whod wd; struct sockaddr_in from; int n, cc, whod, len = sizeof (from); ULONG alrmmask; alrmmask = 1 << alrmsig; n = WaitSelect(s, &readfds, NULL,NULL, NULL, &alrmmask); if (n < 0) - syslog(LOG_ERR, "rwhod: WaitSelect: %s", strerror(errno)); exit(1); " if (alrmmask) onalrm(); /* handles the alarm */ if (n > 0) - cc = recvfrom(s, (char *)&wd, sizeof (wd), 0, (struct sockaddr *)&from, &len); if (cc <= 0) - ________________________________ 9A real code must always test the return values of various services against errors. Thes e tests are partly omitted from this code to show the matters important to this section. 50 Section 3.3 AmiTCP/IP System Manual if (cc < 0) syslog(LOG_ERR, "rwhod: recv: %s", strerror(errno)); continue; " if (from.sin_port != sin.sin_port) - syslog(LOG_ERR, "rwhod: %ld: bad from port", ntohs(from.sin_port)); continue; " ... if (!verify(wd.wd_hostname)) - syslog(LOG_ERR, "rwhod: malformed host name from %lx", ntohl(from.sin_addr.s_addr)); continue; " (void) sprintf(path, "%s/whod.%s", RWHODIR, wd.wd_hostname); whod = open(path, O_WRONLY _ O_CREAT _ O_TRUNC, 0666); ... (void) time(&wd.wd_recvtime); (void) write(whod, (char *)&wd, cc); (void) close(whod); " " " There aretwo separate tasks performed by the server. The first task is to act as a receiver of status information broadcast by other hosts on the network. This job is carried out in the main loopof the program. Packets received at the rwho port are interrogated to insure they've been sent by another rwho server process, then are time stamped with their arrival time and used to update a file indicating the status of the host. When a host has not been heard from foran extended period of time, the database interpretation routines assumethe host is down and indicate such on the status reports. This algorithm is prone toerror as a server may be down while a host is actually up,but serves our current needs. The second task performed by the server is to supply information regarding the status of its host. This involves periodically acquiring system status information, packaging itup in a message and broadcasting it on the local network for other rwho servers to hear. The supply function is triggered by a timer and runs off a signal. Locating the system status information is somewhat involved, but uninteresting. Deciding where to transmit the resultantpacket is somewhat problematical, however. Status information must be broadcast on the local network. For networks which do not support the notionof broadcast another scheme must be used to simulate or replace broadcasting. One possibility is to enumerate the known neighbors (based onthe status messages received from other rwho servers). This, unfortunately, requires some bootstrapping information, for a server will have no idea what machines are its neighbors until it receives status messages from them. Therefore, if all machines on a net are freshly booted, nomachine will have any known neighbors and thus never receive, or send, any status information. This is the identical problem faced by the routing table management process in System Manual AmiTCP/IP Section 3.4 51 propagating routing status information. The standard solution, unsatisfactory as it may be, is to inform one or more servers of known neighbors and request that theyalways communicate with these neighbors. Ifeach server has at least one neighbor supplied to it, status information may then propagate through a neighbor to hosts which are not (possibly) directly neighbors. If the server is able to support networks which provide a broadcast capability, as well as those which do not, then networks with an arbitrary topology may share status information10 It is important that software operating in a distributed environment not have any site-dependent informationcompiled into it. This would require a separate copy of the server ateach host and make maintenance a severe headache. 4.3BSD attempts to isolate host-specific information from applications by providing system calls which return the necessary information11. A mechanism exists, in the form of an IoctlSocket() call, for finding the collection of networks to which a host is directly connected. Further, a local network broadcasting mechanism has been implemented at the socket level. Combining these two features allows a process to broadcast on any directly connected local network which supports the notion of broadcasting in asite independent manner. This allows 4.3BSD to solve the problem of decidinghow to propagate status information in the case of rwho, or more generally in broadcasting: Such status information is broadcast to connected networks at the socket level, where the connected networks have been obtained via the appropriate ioctl calls. The specifics of such broadcastings are complex, however, and will be covered in section 3.4. 3.4 Advanced Topics A number of facilities have yet to be discussed. Formost users of the AmiTCP/IP the mechanisms already described will suffice in constructing distributed applications. However, others will find the need to utilize some of the features which we consider in this section. 3.4.1 OutOf Band Data The stream socket abstraction includes the notion of ``out of band'' data. Out of band data is a logically independent transmission channel associated with each pair of connected stream sockets. Out of band data is delivered to the user independently of normal data. The abstraction defines that the out of band data facilities must support the reliable delivery of at least one out of band message at a time. This message may contain at least one byte of data, and at least one message may be pending delivery to the user at any onetime. For communications protocols which support only in-band signaling (i.e. the urgent data is ________________________________ 10One must, however, be concerned about loops. That is, if a host is connected to multiple networks, it willreceive status information from itself. This can lead to an endless, wasteful, exchange of information. 11An example of such a system call is the gethostname() call which returns the host's official name. 52 Section 3.4 AmiTCP/IP System Manual delivered in sequence with the normal data), the system normally extracts the data from the normal data stream andstores it separately. This allows users to choose between receiving the urgent data in order and receiving it out of sequence without having to bufferall the intervening data. It is possib* *le to ``peek'' (via MSG_PEEK) at out of band data. If the socket has an owner, a signal is generated when the protocolis notified of its existence. A process can set the task to be informed by a signal via the appropriate IoctlSocket() and SetSocketSignals() calls, as described below in section 3.4.3. If multiple sockets may have out of band data awaiting delivery, a select() call for except* *ional conditions may be used to determine those sockets with such data pending. Neit* *her the signal nor the select() indicate theactual arrival of the out-of-band data, but only notification that it is pending. In addition to the information passed, a logical mark is placed in the data stream to indicate the point at which the out of band data was sent12. The remote login and remote shell applications use this facility to propagate signals between client andserver processes. When a signal flushs any pending output from the remote process(es), all data up to the mark in the data stream is discarded. To send an out of band message the MSG_OOB flag is supplied to a send() or sendto() calls, while to receive outof band data MSG_OOB should be indicated when performing a recvfrom() or recv() call. To find out if the read pointer is currently pointing at the mark in the data stream, the SIOCATMARK ioctl is provided: IoctlSocket(s, SIOCATMARK, &yes); If yes is a 1 on return, the next read will return data after the mark. Otherwise (assuming out of band data hasarrived), the next read will provide data sent by the client prior totransmission of the out of band signal. The routine used in the remote login process to flush output on receipt of an interrupt or quit signal is shown below: #include #include ... oob() - int mark; char waste[BUFSIZ]; /* flushterminal I/O on receipt of out of band data */ for (;;)- if (IoctlSocket(rem, SIOCATMARK,&mark) < 0) - perror("IoctlSocket"); break; " if (mark) break; recv(rem, waste, sizeof (waste),0); ________________________________ 12AmiTCP/IP follows the BSD interpretation of the RFC 793 in which the concept of out-of-band data is introduced. The BSD interpretation is in conflict with (later) defined Host Requirements laid down in RFC 1122. System Manual AmiTCP/IP Section 3.4 53 " if (recv(rem, &mark, 1, MSG_OOB) < 0) - perror("recv"); ... " ... " The normal data up to the mark if first read (discarding it), then the out-of-band byte is read. A processmay also read or peek at the out-of-band data without first reading up to the mark. This is more difficult when the underlying protocol delivers the urgent data in-band with the normal data, and only sends notification of its presence aheadof time (e.g., the TCP protocol used to implement streams in the Internet domain). With such protocols, the out-of-band byte may not yet have arrived when a recv() is done with the MSG_OOB flag. In that case, the call will return an error of EWOULDBLOCK. Worse, there may be enoughin-band data in the input buffer that normal flow control prevents the peer from sending the urgent data until the buffer is cleared. The process must then read enough of the queued data that the urgent data may bedelivered. Certain programs that use multiple bytes of urgent data and must handle multiple urgent signals (e.g., telnet) need to retain the position of urgent data within the stream. This treatment is available as a socket-level option, SO_OOBINLINE; see function reference for setsockopt() for usage. With this option, the positionof urgent data (the ``mark'') is retained, but the urgent data immediately follows the mark within the normal data stream returned without the MSG_OOB flag. Reception of multiple urgent indicationscauses the mark to move, but no out-of-band data are lost. 3.4.2 Non-Blocking Sockets It is occasionally convenient to make use of sockets which do not block; that is, I/O requests which cannot complete immediately and would therefore cause the process to be suspended awaiting completion are not executed, and an error code is returned. Once a sockethas been created via the socket() call, it may be markedas non-blocking by IoctlSocket() as follows: #include ... int s; long yes = TRUE; ... s = socket(AF_INET, SOCK_STREAM, 0); ... if (IoctlSocket(s, FIONBIO, &yes) < 0) perror("IoctlSocket FIONBIO"); exit(1); " ... When performing non-blocking I/O on sockets, one must be careful to check for the error EWOULDBLOCK (storedin the global variable errno), 54 Section 3.4 AmiTCP/IP System Manual which occurs when an operation would normally block, but the socket it was performed on is marked as non-blocking. In particular, accept(), connect(), send(), sendto(), recv() andrecvto() can all return EWOULDBLOCK, and processes should be prepared to deal with such return codes. If an operation such as a send() cannot be donein its entirety, but partial writes are sensible (for example, when using a stream socket), the data that can be sent immediately will be processed, and the return value will indicate the amount actually sent. 3.4.3 Signal Driven Socket I/O The AmiTCP/IP allows a task to be notified via a signal when a socket has either normal or out-of-band data waiting to be read. Use of this facility requres four steps: 1. The signals to be used must be allocated with Exec AllocSignal() call. 2. The allocated signal(s) must be registered to the AmiTCP/IP with the SetSocketSignals() call. The signals registered with SetSocketSignals() affect all sockets of the calling task, so this is usually done only after OpenLibrary() call. 3. The owner of the socket must be set to the task itself (note that the owner of a socket is unspecified by default). This is accomplished by the use of an IoctlSocket() call. 4. Asynchronous notification for the socket must be enabled with another IoctlSocket() call Note that it is application's responsibility to react on received signals. Sample code to allow a given process to receive information on pending I/O requests as they occur for a sockets is given below: #include #include ... BYTE SIGIO = -1, SIGURG = -1; ... struct Task *thisTask = FindTask(NULL); /* our task pointer */ long yes = TRUE; /* Allocate signals for asynchronous notification */ if ((SIGIO = AllocSignal(-1)) == -1) - fprintf(stderr, "allocSignal failed."n"); exit(1); " atexit(freeSignals); /* free allocated signals on exit */ if ((SIGURG = AllocSignal(-1)) == -1) - fprintf(stderr, "allocSignal failed."n"); exit(1); " System Manual AmiTCP/IP Section 3.4 55 /* Set socket signals for this task */ SetSocketSignals(SIGBREAKF_CTRL_C, 1 << SIGIO, 1 << SIGURG); /* Set the process receiving SIGIO/SIGURG signals to us */ if (IoctlSocket(s, FIOSETOWN, &thisTask) < 0) - perror("IoctlSocket FIOSETOWN"); exit(1); " /* Allow receipt of asynchronous I/O signals */ if (IoctlSocket(s, FIOASYNC, &yes) < 0) - perror("IoctlSocket FIOASYNC"); exit(1); " 3.4.4 Selecting Specific Protocols If the third argument to the socket() call is 0, socket will select a default protocol to use with the returned socket of the type requested. The default protocol is usually correct,and alternate choices are not usually available. However, when using ``raw'' socketsto communicate directly with lower-level protocols or hardware interfaces, the protocol argument may be important for setting updemultiplexing. For example, raw sockets in the Internet family may be used to implement a new protocol above IP, and the socket will receive packets only for the protocol specified. To obtain a particular protocol one determines the protocol number as defined within the communication domain. For the Internet domain one may use one of the library routines discussed in section 3.2, such as getprotobyname(): #include #include #include #include ... pp = getprotobyname("newtcp"); s = socket(AF_INET, SOCK_STREAM, pp->p_proto); This would result in a socket s using astream based connection, but with protocol type of ``newtcp'' instead of the default ``tcp.'' 3.4.5 Address Binding As was mentioned in section 3.1, bindingaddresses to sockets in the Internet domains can be fairly complex. As a brief reminder, these associations are composed of local and foreign addresses, and local and foreign ports. Port numbers are allocated out of separate spaces, one for each system and one for each domainon that system. Through the bind() call, a process may specify halfof an association, the part, while the connect() and accept() calls are 56 Section 3.4 AmiTCP/IP System Manual used to complete a socket's associationby specifying the part. Since the association iscreated in two steps the association uniqueness requirement indicated previously could be violated unless care is taken. Further, it is unrealistic to expect user programs to always know proper values touse for the local address and local port since a host may reside on multiplenetworks and the set of allocated port numbers is not directly accessibleto a user. To simplify local address binding in the Internet domain the notion of a ``wildcard'' address has been provided. When an address is specified as INADDR_ANY (a manifest constant defined in file netinet/in.h), the system interprets the address as ``any valid address''. For example, to bind a specific port number to a socket,but leave the local address unspecified, the following code might beused: #include #include ... struct sockaddr_in sin; ... s = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(MYPORT); bzero(sin.sin_zero, sizeof(sin.sin_zero)); bind(s, (struct sockaddr *) &sin, sizeof (sin)); Sockets with wildcarded local addressesmay receive messages directed to the specified port number, and sent to any of the possible addresses assigned to a host. For example, if a host has addresses 128.32.0.4 and 10.0.0.78, and a socket is bound as above, the process will be able to accept connection requests which are addressed to 128.32.0.4 or 10.0.0.78. If a server process wished to only allow hosts on a given network connect to it, it would bind theaddress of the host on the appropriate network. In a similar fashion, a local port may be left unspecified (specified as zero), in which case the system willselect an appropriate port number for it. For example, to bind a specific local addressto a socket, but to leave the local port number unspecified: hp = gethostbyname(hostname); if (hp == NULL) - ... " bzero(&sin, sizeof(sin)); bcopy(hp->h_addr, (char *) sin.sin_addr, hp->h_length); sin.sin_port = htons(0); bind(s, (struct sockaddr *) &sin, sizeof (sin)); The system selects the local port numberbased on two criteria. The first is that on 4BSD systems, Internetports below IPPORT_RESERVED (1024) are reserved for privileged processes13 ; Internet ports above ________________________________ 13All processes in AmigaOS are considered as privileged. System Manual AmiTCP/IP Section 3.4 57 IPPORT_USERRESERVED (5000) are reserved for non-privileged servers. The second is that the port number is not currently bound to some other socket. In order to find a free Internet port number in the privileged range the rresvport() library routine may be used as follows to return a stream socket in with a privileged portnumber: int lport = IPPORT_RESERVED - 1; int s; s = rresvport(&lport); if (s < 0) - if (errno== EAGAIN) fprintf(stderr, "socket: all ports in use"n"); else perror("rresvport: socket"); ... " The restriction on allocating ports wasdone to allow processes executing in a secure environment to perform authentication based on the originating address and port number. For example, therlogin command allows users to log in across a networkwithout being asked for a password, if two conditions hold: First, the name of the system the user is logging in from is in the file AmiTCP:db/hosts.equiv14 on the system he is logging into (or the system name and the user name are in the user's .rhosts file in the user's home directory), and second, that the user's rlogin process is coming from a privileged port on the machine from which he is logging. The port number and networkaddress of the machine from which the user is logging in can be determined either by the from result of the accept() call, or from thegetpeername() call. In certain cases the algorithm used by the system in selecting port numbers is unsuitable for an application. This is because associations are created in a two step process. For example, the Internet file transfer protocol, FTP, specifies that data connections must always originate from the same local port. However, duplicateassociations are avoided by connecting to different foreign ports. Inthis situation the system would disallow binding the same local address and port number to a socket if a previous data connection's socket still existed. To override the default port selection algorithm, anoption call must be performed prior to address binding: ... long on = 1; ... setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); bind(s, (struct sockaddr *) &sin, sizeof (sin)); With the above call, local addresses maybe bound which are already in use. This does not violate the uniqueness requirementas the system still checks at connect time to be sureany other sockets with the same local address and port do not have the same foreign address and port. If the association already exists, the error EADDRINUSE is returned. ________________________________ 14In UNIX /etc/hosts.equiv 58 Section 3.4 AmiTCP/IP System Manual 3.4.6 Broadcasting And Determining Network Configuration By using a datagram socket, it is possible to send broadcast packets on many networks supported by the system. The network itself must support broadcast; the system provides no simulation of broadcast in software. Broadcast messages can place a high loadon a network since they force every host on the network to service them. Consequently, the ability to send broadcast packets has been limitedto sockets which are explicitly marked as allowing broadcasting. Broadcast is typically used for one of two reasons: it is desired to find a resource on a local network without prior knowledge of its address, or important functions such as routing require that information be sent to allaccessible neighbors. To send abroadcast message, a datagram socket should be created: s = socket(AF_INET, SOCK_DGRAM, 0); The socket is marked as allowing broadcasting, long on = 1; setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)); and at least a port number should be bound to the socket: sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(MYPORT); bzero(sin.sin_zero, sizeof(sin.sin_zero)); bind(s, (struct sockaddr *) &sin, sizeof (sin)); The destination address of the message to be broadcast depends on the network(s) on which the message is to bebroadcast. The Internet domain supports a shorthand notation for broadcast on the local network, the address INADDR_BROADCAST (defined in netinet/in.h). To determine the list of addresses for all reachable neighbors requires knowledge of the networks to which the host is connected. Since this information should be obtained in a host independent fashion and may be impossible to derive, 4.3BSD provides a method of retrieving this information from the system data structures. The SIOCGIFCONF IoctlSocket()call returns the interface configuration of a host in theform of a single ifconf structure; this structure contains a ``data area'' which is made up of an array of of ifreq structures, one for each network interface to which the host is connected. These structures are defined in net/if.h asfollows: struct ifconf - int ifc_len; /* size of associated buffer */ union - caddr_t ifcu_buf; struct ifreq *ifcu_req; " ifc_ifcu; "; #define ifc_buf ifc_ifcu.ifcu_buf/* buffer address */ #define ifc_req ifc_ifcu.ifcu_req/* array of structures returned */ #define IFNAMSIZ 64 System Manual AmiTCP/IP Section 3.4 59 struct ifreq - char ifr_name[IFNAMSIZ]; /*if name, e.g. "en0" */ union - struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; short ifru_flags; caddr_t ifru_data; " ifr_ifru; "; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ The actual call which obtains the interface configuration is struct ifconf ifc; char buf[BUFSIZ]; ifc.ifc_len = sizeof (buf); ifc.ifc_buf = buf; if (IoctlSocket(s, SIOCGIFCONF, (char *) &ifc) < 0) - ... " After this call buf will contain one ifreq structure for each network to which the host is connected, and ifc.ifc_len will have been modified to reflect the number of bytes used by theifreq structures. For eachstructure there exists a set of ``interface flags'' which tell whether the network corresponding to that interface is up or down, point to point or broadcast, etc. The SIOCGIFFLAGS IoctlSocket() retrieves these flags for an interface specified by an ifreq structure as follows: struct ifreq *ifr; ifr = ifc.ifc_req; for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) - /* * We must be careful that we don't use an interface * devoted to anaddress family other than those intended; * if we were interested in NS interfaces, the * AF_INET wouldbe AF_NS. */ if (ifr->ifr_addr.sa_family != AF_INET) continue; if (IoctlSocket(s, SIOCGIFFLAGS, (char *) ifr) < 0) - ... " /* 60 Section 3.4 AmiTCP/IP System Manual * Skip boring cases. */ if ((ifr->ifr_flags & IFF_UP) == 0 __ (ifr->ifr_flags & IFF_LOOPBACK) __ (ifr->ifr_flags & (IFF_BROADCAST_ IFF_POINTTOPOINT)) == 0) continue; Once the flags have been obtained, the broadcast address must be obtained. In the case of broadcast networks this is done via the SIOCGIFBRDADDR IoctlSocket(), while forpoint-to-point networks the address of the destination host is obtained with SIOCGIFDSTADDR. struct sockaddr dst; if (ifr->ifr_flags & IFF_POINTTOPOINT) - if (IoctlSocket(s, SIOCGIFDSTADDR, (char *) ifr) < 0) - ... " bcopy((char *) ifr->ifr_dstaddr, (char *) &dst, sizeof (ifr->ifr_dstaddr)); " else if (ifr->ifr_flags & IFF_BROADCAST) - if (IoctlSocket(s, SIOCGIFBRDADDR, (char *) ifr) < 0) - ... " bcopy((char *) ifr->ifr_broadaddr, (char *) &dst, sizeof (ifr->ifr_broadaddr)); " After the appropriate ioctl's have obtained the broadcast or destination address (now in dst), the sendto() callmay be used: sendto(s,buf, buflen, 0, (struct sockaddr *)&dst, sizeof (dst)); " In the above loop one sendto() occurs for every interface to which the host is connected that supports the notion of broadcast or point-to-point addressing. If a process only wished to send broadcastmessages on a given network, code similar to that outlined above would be used, but the loop would need to find the correct destination address. Receivedbroadcast messages contain the senders address and port, as datagram sockets are bound before a message is allowed to go out. AmiTCP/IP specific extensions Extensions to interface ioctls The following ioctls are used to configure protocol and hardware specific properties of a sana_softc interface. They are used in the AmiTCP/IP only. SIOCSSANATAGS Set SANA-II specific properties with a tag list. SIOCGSANATAGS Get SANA-II specific properties into the wiretype_parameters structure and a user tag list. These ioctls use the following structure as a argument: System Manual AmiTCP/IP Section 3.4 61 struct wiretype_parameters - ULONG wiretype; /* the wiretype of the interface */ WORD flags; /* iff_flags */ struct TagItem *tags; /* tag list user provides */ "; SIOCGARPT Getthe contents of an ARP mapping cache into a struct arpreq table. This ioctl takes the following arptabreq structure as an argument: /* * An AmiTCP/IP specific ARP table ioctl request */ struct arptabreq - struct arpreq atr_arpreq; /* To identify theinterface */ long atr_size; /* # of elementsin atr_table */ long atr_inuse; /* # of elements in use */ struct arpreq *atr_table; "; The atr_arpreq specifies the used interface. The hardware address for the interface is returned in the arp_ha field of atr_arpreq structure. The SIOCGARPT ioctl reads at most atr_size entries from the cache into the user supplied buffer atr_table, if it is not NULL. Actual amount of returned entries is returned in atr_size. The current amount of cached mappings is returned in the atr_inuse. 3.4.7 Socket Options It is possible to set and get a number of options on sockets via the setsockopt() and getsockopt() calls. These options include such things as marking a socket for broadcasting, not to route, to linger on close, etc. The general forms of the calls are: setsockopt(s, level, optname, optval, optlen); and getsockopt(s, level, optname, optval, optlen); The parameters to the calls are as follows: s is the socket on which the option is to be applied. level specifies the protocol layer on which the option is to be applied; in most cases this is the ``socket level'', indicated by the symbolic constant SOL_SOCKET, defined in sys/socket.h. The actual option is specified in optname, and is a symbolic constant also defined in sys/socket.h. optval and optlen pointto the value of the option (in most cases, whether the option is to be turned on or off), and the length of the value of the option, respectively. For getsockopt(), optlen is a value--resultparameter, initially set to the 62 Section 3.4 AmiTCP/IP System Manual size of the storage area pointed to by optval, and modified upon return to indicate the actual amount of storageused. An example should help clarify things. It is sometimes useful to determine the type (e.g., stream, datagram, etc.) ofan existing socket; programs under inetd (described in section 3.4.8) may need to perform this task. This can be accomplished as follows via theSO _TYPE socket option and the getsockopt() call: #include #include long type, size; size = sizeof (type); if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &size) < 0) - ... " After the getsockopt() call, type will be set to the value of the socket type, as defined in sys/socket.h. If, for example, thesocket were a datagram socket, type would have the value corresponding to SOCK_DGRAM. 3.4.8 Inetd One of the daemons provided with AmiTCP/IP is inetd, the so called ``internet super--server.'' Inetd is invoked at start-up time, and determines the servers, for which it isto listen, from the file AmiTCP:db/inetd.conf15. Once this information has been read and a pristine environment created, inetd proceeds to create one socket for each service it is to listen for, binding the appropriate port number to each socket. Inetd then performs a select() on all these sockets for read availability, waiting for somebody wishing a connection to the service corresponding to that socket. Inetd then performs an accept() on the socket in question, releases the socketwith a ReleaseSocket() call and starts the appropriate server. Servers making use of inetd are considerably simplified, as inetd takes care of the majority of the work required in establishing a connection. The server invoked by inetd expects thesocket connected to its client to be found by calling ObtainSocket(). The client socketID for the server is found in a DaemonMessage structure given to the server process. Usually the netlib:autoinitd.o module takes care of obtaining the client socket into global variable server_socket. For practical purposes the code might assume this socket to be 0. One callwhich may be of interest to individuals writing servers under inetd is the getpeername() call, which returns the address of the peer (process) connected on the other end ofthe socket. For example, to log the Internet address in ``dot notation''(e.g., ``128.32.0.4'') of a ________________________________ 15In UNIX systems /etc/inetd.conf. System Manual AmiTCP/IP Section 3.5 63 client connected to a server under inetd, the following code might be used: struct sockaddr_in name; int namelen = sizeof (name); ... if (getpeername(0, (struct sockaddr *)&name, &namelen) < 0) - syslog(LOG_ERR, "getpeername: %m"); exit(1); " else syslog(LOG_INFO, "Connection from %s", inet_ntoa(name.sin_addr)); ... While the getpeername() call is especially useful when writing programs to run with inetd, it can be used underother circumstances. Sources for a very simple TCP protocol server is included with AmiTCP/IP as an example. 3.5 Deviation From Berkeley Sockets This section discusses the differences between the API of the AmiTCP/IP and the 4.3BSD. They are not so numerousas it might seem to, but worth taking attention to when porting existing 4.3BSD software to AmiTCP/IP. 3.5.1 Opening and Closing the Shared Library Since the API is provided as a shared library, it must be opened to be able to access the functions it provides. Note that any two tasks may not share a socket library base, since the base contains task specific information. AmiTCP/IPdoes resource tracking based on the information stored in a library base, so it is essential that the library is closed after use, since the resources used by the base aregone if the application exits without closing the base. See section 3.1.2 for examples and more discussion on the subject. 3.5.2 Naming Conventions of the API Functions The API functions which preserve the semantics of the BSD calls are named the same as the original functions. In the name of binary compatibility between different C compilers the functions which either take a structure as an argument or return a structure asa value had to be changed not to do so. These functions are named differently; all words in these function names begin with an upper caseletter. Inlinefunctions16 are provided with the original semantics, however. This makes it possible to keep using the original functions when writing the code and still be binary compatible. The inline functions are mostly trivial; for example the select() call is actually an inlinewhich calls WaitSelect() with last argument as NULL. ________________________________ 16Or linker stubs in compilers with no inline functions. 64 Section 3.5 AmiTCP/IP System Manual This is amatter which should be totally invisible for C users, but assembler programmers should take attention and be sure to pass arguments as described in the function reference for the non-inline versions. 3.5.3 errno Unix libraries return error values in aglobal variable named errno. Since a shared library cannot know the address of any variables of an application, the address of the errno must be explicitly told to the AmiTCP/IP. An alternative is to use Errno() call to fetch the error value, but since the first method needsno modifications to the existing sources (besides calling SetErrnoPtr() once in the beginning), it is the preferred method. Section 3.1.2 contains examples andmore discussion about the matter. 3.5.4 NewField in the sockaddr Structures Since AmiTCP/IP is based on the BSD Net/2 release, it has few differences to the 4.3BSD. Most notableone is that the sockaddr and sockaddr_in structureshave a new field telling the length of the structure. These are named as sa_len and sin_len respectively. These fields are used by the AmiTCP/IP to determine the real length of the address given. In addition the sockaddr_in structure has a field named sin_zero, which should be initialized to zero before passed to the AmiTCP/IP, since any garbage left there will be used by the routing facility (which obviously leads to undesired behaviour). 3.5.5 Linger Time The unit of the linger time of a socketis a second. The Net/2 code seemed to use ticks17. 3.5.6 Transferring Sockets from a Task to Another Since AmigaOS has no fork() call, in which the child process inherits the file descriptors, and hence sockets, a mechanism for transferring sockets from a task to another must be provided. This is accomplished by the calls ReleaseSocket(), ReleaseCopyOfSocket() and ObtainSocket(), which release a socket, a copy of a socket andobtain a released socket, respectively. An id is given to a socket placed in thelist of released sockets. This id can be either unique or be based on aservice number in cases where it is irrelevant which instance of the server process for the service in question obtains the socket. If an unique id is used, the releasing task is responsible of transferring the id to the obtaining task. ________________________________ 17One tick is 1/hz:th of a second, where hz is the frequency of the electricity of the wall socket. System Manual AmiTCP/IP Section 3.5 65 This feature affects the server processes only, since the clients usually create the socket(s) on their own. 3.5.7 Ioctl Differences The Unix ioctl() function is renamed asIoctlSocket() in AmiTCP/IP to avoid name clashes with some C runtime libraries. Followingsummarizes other differences in the ioctl calls: 1. FIOCLEX and FIONCLEX are silently ignored, that is, they are accepted, but have no effect. Whether sockets should be closed on exec() or not is irrelevant, since AmigaOS has no such feature (see discussion about fork() above). 2. FIOSETOWN and SIOCSPGRP take a pointer to a struct Task * as an argument instead of a pointer to a process (or group) id. Note that if the task in question has not opened the bsdsocket.library the owner of the precess is set to NULL (disabled). The task pointer is used as the receiver of the asynchronous notification signals if asynchronous notification is enabled. 3. FIOGETOWN and SIOCGPGRP take a pointer to a struct Task * as an argument in which the current task pointer of the owner of the socket in question is placed on return. 3.5.8 Signal Handling There is a fundamental difference between BSD Unix and Amiga signal handling and the system call interface. In the Unix systems a received signal may interrupt a process executinga system call. If there is a signal handler installed, it can be executed before the system call returns to the main execution branch with an error code. However,there are some system calls which may not be interrupted. If a Unix process has a negative priority,tsleep() does not wake up until the specified condition is met. The interrupted system call does not have any unrecoverable effects, the execution of the program may continue after the errno is checked against other errors than EINTR. In the AmigaOS, Exec, there are no specific system calls. All OS functions are provided by shared libraries. There areeither no separate kernel and user memory spaces, the one common memory space is shared by all processes. The IO system is based on messages, which are implemented as shared memory areas. When a program receives a message to a port, it is delivered a signal associated with the port. While itis possible to use signal handlers with Exec, they are even more dangerous to use and restricted than in Unix systems. This is not recommended, since the exception handlermust behave like any real interrupt handler. Calls provided by AmiTCP/IP are notcallable from interrupts. Further, it is not possible to interrupt asystem call implemented as a shared library function. The application must itself react on receipt of the signals. The recommended way of handling these signals is by the normal Wait() of by 66 Section 3.5 AmiTCP/IP System Manual AmiTCP/IP call WaitSelect(), which allows an application to specify a signal mask which should abort the selection. The application then checks the received signals and calls appropriate handler for the signal. 3.5.9 Asynchronous I/O AmigaOS does not have any reserved signals for networking, such as SIGIO or SIGURG in Unix systems, and so the scheme used in asynchronous notification must be changed a little. The application can set a group of signal masks, with function named SetSocketSignals(), to be used by the AmiTCP/IP. First argument specifies the signal mask which should break the blocking of the blocking socket calls. It is by default set to the signal for CTRL-C. Second argument specifies the signal(s) to be sent when asynchronous notification for readiness to read is necessary. Thismask lets the application define which signal should be used as replacement for SIGIO signal of the Unix systems. Third and last argument specifies the corresponding mask for the asynchronousnotification of urgent (out-of-band) data (SIGURG). These lasttwo masks are zero by default. Note thatthere is no way to query the current settings of these signals form the AmiTCP/IP, so the application must store the signal numbers (or masks) for later use. Also note that the break mask must be explicitly given if SetSocketSignals() is called, since the values supplied override the default settings. 3.5.10 Constructing an Event Loop Amiga programs are often constructed around an event loop, in which Wait() function is used to wait for somesubset of given signals to arrive. When a signal is received, some actions are taken and if IO is performed, it is usually asynchronous. Many Unixprograms use to do synchronous IO and let the signal handlers to handle special events (window size changes, timeouts, etc.). This can be emulated to some extent with AmigaOS,since it is possible to specify an exeption function to handle receptionof given signals. This is very limited, though, since the exeption codeis executed at true interrupt level, and may thus pre-empt the main process in an arbitrary location. Also note that a very limited set of shared library functions can be called while in interrupt, especially note that any AmiTCP/IP function may NOT be called from interrupt code. AmiTCP/IPoffers remedy for this, however. The application can use WaitSelect() to handle both Amiga signals and socket IO multiplexing. Selecting assures that the following socket calls will not block18. Another possiblility is to use signal driven socket IO (see section 3.4.3). Yet another possibility is to specify a special break mask with SetSocketSignals() function. The signals in the mask cause any blocking socket IO routine to return with the error code EINTR. Note that the ________________________________ 18See NOTES section of the reference for the WaitSelect(). System Manual AmiTCP/IP Section 3.5 67 signals are not cleared in this procedure. The Wait()with the same signal mask can be used to determine (and clear) the received signals. This allows the usage of synchronous socket IO, but the EINTR error code must be checked after each failing call. 3.5.11 ''Killing'' the Processes In AmigaOS the applications must co-operate with the OS for the user to be able to stop them. This is why the blocking operations of the AmiTCP/IP can be aborted. By default the reception ofCTRL-C signal aborts any blocking call. The call returns an error value (in errno) of EINTR when aborted. In addition the signal which caused the break will remain set for the application to be able to react on it in its normal event processing. This means that the application neednot specially check for EINTR after every socket callas long as they eventually check for the break signal. All sockets left open by the application are closed by the CloseLibrary() call. You may left the sockets open when aborting the program, because the socket library is closed automatically during the exit process if either autotermination function (specific to SAS C) or ANSI atexit() function is installed before the exit is done. . The signals which cause the abort can be set with the SetSocketSignals() call. The break signal mask is given as the first argument. Calling this function discards the previousvalues of the sockets signal masks. Aborting can be disabled by giving the mask as 0L. See section 3.5.9 for more discussion about the SetSocketSignals() call. 3.5.12 WaitSelect() In AmiTCP/IP no other than socket I/O can be multiplexed with the select() call. This may be a major pain as I/O is normally multiplexed with an Wait() loop, waiting for given signals to arrive. This is the motivation for the WaitSelect() call. It combines theselection and waiting in a single call19. The WaitSelect() takes one argument in addition to the normal select() call. It is a pointerto signal mask to wait for in addition to the signals thatthe AmiTCP/IP uses internally. If any of these signals is received, they are returned as a result in the same signal mask. Signals specified in the given signal mask override the signals of the break mask (see previous section). If the same signal is specified in both the SIGINTR mask and the mask given to the WaitSelect(), the reception of the signal causes it tobe cleared and returned in the mask as the result. WaitSelect() can be used as replacement for the Wait() in applications which require to multiplex both socket related and other Amiga I/O. ________________________________ 19This feature was really easy to implement, since AmiTCP/IP uses a Wait() to wait for I/O events itself. 68 Section 3.5 AmiTCP/IP System Manual Chapter 4 Internal Description 4.1 Source File Structure The source tree of AmiTCP/IP is dividedto few main parts: 1. Directory sys contains BSD Unix system header files, which are ported to the Amiga environment. 2. Directory net contains modules for the general networking services. They are independent of any particular protocol family. 3. Directory netinet contains the modules for the internet (inet) protocol family. IP, ICMP, TCP and UDP are internet protocols. 4. Directory kern contains modules, which provide the BSD kernel environment for the networking routines. 5. Directory api contains the BSD socket compatible shared library API code. The filesare briefly described in the following paragraphs. Note that some of the header files are actually located to the NETINCLUDE:1 directory. 4.1.1 System Include Files General Headers sys/cdefs.h Definitions to harmonize various C language dialects. sys/param.h General machine independent parameter definitions. sys/time.h Definition of structure timeval. sys/types.h Common C type definitions and file descriptorset macros for select(). BSD Socket API ________________________________ 1See section 3.1.3 on page 30. 69 70 Section 4.1 AmiTCP/IP System Manual sys/errno.h Error code definitions for system functions. sys/ioctl.h Definitions for socket IO control. sys/socket.h Definitions related to sockets: types, address families, options and prototypes. sys/uio.h IO structure definition for sendmsg() and recvmsg()2. BSD Kernel Data Structures sys/domain.h Domain structure and global domain pointer declarations. sys/kernel.h Global kernel variable definitions (used throughoutthe kernel). sys/malloc.h Defines the bsd_malloc() and bsd_free() functions. sys/mbuf.h Mbuf structure definition and inline macros. sys/protosw.h Protocol switch structure definition with related definitions (options, actions, etc.). sys/queue.h General queue data structures. sys/socketvar.h Socket structure definition and related utility macros. sys/synch.h Declarations for tsleep and spl functions. sys/syslog.h Logging related definitions. sys/systm.h System wide definitions and prototypes. 4.1.2 Protocol Independent Network Routines Network Interface net/if.c General network interface routines. net/if.h Defines the interface for network adapter drivers. net/if_arp.h General protocol independent ARP structures. net/if_dl.h Defines the Link Level sockaddr structure. net/if_loop.c Loopback device routines. net/if_sana.c Interface module for the SANA-IInetwork adapter drivers. net/if_sana.h Defines the interface for the SANA-II network adapter drivers. net/if_types.h Interface type numbers. Obsolete. net/netisr.h and net/netisr.c Defines the network input queue scheduling routines. net/sana2arp.c ARP routines for Sana-II devices. net/sana2arp.h SANA-II private ARP headers. net/sana2copybuff.c Buffer management routines called from SANA-II ________device_driver.__________ 2These functions are not implemented in this release of the AmiTCP/IP System Manual AmiTCP/IP Section 4.1 71 net/sana2errno.h SANA-II error lists and printing header. net/sana2request.c Moduleto handle SANA-II IO Requests. net/sana2request.h Inlineroutines to manage different SANA-II IO requests. net/sana2tags.c Common customization parameters for the sana_softc network interface. net/sana2tags.h Defines the tags to customize sana_softc network interface. netlib:sana2perror.c Printing routines for SANA-II error messages. Routing net/radix.c Routines for searching, adding and removing data items in the radix binary tree. net/radix.h Defines the radix tree data structures. net/route.c General, protocol independent routing functions. net/route.h Defines data structures for routing entries,tables and statistics. net/rtsock.c The socket interface to the routing information. Raw Sockets net/raw_cb.c Routines to manage the rawprotocol control blocks. net/raw_cb.h The raw protocol control block definition. net/raw_usrreq.c The raw socket interface to the low level protocols and network adapters. 4.1.3 Internet Protocol Modules Inet Domain netinet/in.c Generic Internet addressing routines. netinet/in.h Protocol numbers, port conventions, inet address definitions. netinet/in_cksum.c Calculates checksum for internet protocol headers. netinet/in_pcb.c Generic internet protocol routines, binding, addressing. netinet/in_pcb.h Declares generic internet protocol control block. netinet/in_proto.c Defines internet protocol control blocks. netinet/in_systm.h Some network byte order type definitions. netinet/in_var.h Define an interface address structure for internet. IP, ICMP netinet/icmp_var.h ICMP statistics. netinet/ip.h IP packet header, packet options, timestamp. 72 Section 4.1 AmiTCP/IP System Manual netinet/ip_icmp.c Routines to generate, receive and reflect ICMP packets. netinet/ip_icmp.h ICMP packet structure. netinet/ip_input.c IP input, packet reassemble and packet forwarding. netinet/ip_output.c IP output, packet fragmenting. netinet/ip_var.h Define IP statistics, external IP packet header, reassemble queues structures. netinet/raw_ip.c Provide a raw interface to the IP protocol. TCP netinet/tcp.h Define the TCP packet structure. netinet/tcp_debug.c TCP debugging routines. netinet/tcp_debug.h Header for TCP debugging. netinet/tcp_fsm.h TCP Finite State Machine states. netinet/tcp_input.c TCP input routines. netinet/tcp_output.c TCP output routines. netinet/tcp_seq.h TCP sequence numbering. netinet/tcp_subr.c Various TCP subroutines for initializing, connection maintenance etc. netinet/tcp_timer.c TCP timeout routines. netinet/tcp_timer.h TCP timing constants. netinet/tcp_usrreq.c Process TCP user requests (send, timeout), attach, disconnect. netinet/tcp_var.h Define TCP control block and TCP statistics. netinet/tcpip.h Define the overlaid TCPIP packet header structure. UDP netinet/udp.h Define the UDP packet structure. netinet/udp_usrreq.c Routines to UDP output, input and notification. netinet/udp_var.h Define UDPIP packet overlay, UDP statistics. 4.1.4 BSDKernel Service Modules BSD Kernel Support kern/amiga_includes.h Include file which includes all amiga specific include files. kern/amiga_main.c Main module of the AmiTCP/IP. kern/amiga_subr.h Miscellaneous function definitions (usually short inline functions). kern/amiga_time.c Timer module for the timeout functions. kern/amiga_time.h Amiga timer.device related functions. System Manual AmiTCP/IP Section 4.1 73 kern/kern_malloc.c Malloc & free related functions. kern/kern_synch.c tsleep and spl function definitions. kern/uipc_mbuf.c Mbuf functions. Socket Level Functions kern/uipc_domain.c Domain functions, especially pfslowtimo() and pffasttimo(). kern/uipc_socket.c Higher level so-level functions (socreate(), sobind() etc.). kern/uipc_socket2.c Lower level so-level functions (soisconnecting(), soqremque(), sowakeup() etc.). NETTRACE Maintenance Process Support kern/amiga_config.c Configuration and ARexx command support routines. kern/amiga_config.h Defines the structure for configuration variables. kern/amiga_cstat.c Query support routines. kern/amiga_log.c Functions for initialization of log task and code for task itself. kern/amiga_log.h Header file for logging functions. kern/amiga_netdb.c Network database parsing and support functions. kern/amiga_netdb.h Declares the network database structures and types. kern/amiga_rexx.c Arexx-interface. kern/amiga_rexx.h Arexx-interface definitions. kern/config_var.awk Awk script to generate both code and documentation from the file kern/variables.src. kern/subr_prf.c Interfaces for (s)printf(), panic() and log() kern/variables.src Definition and documentation for configuration variables 4.1.5 BSDSocket API Shared Library Interface api/allocdatabuffer.c Client data buffer allocation functions. api/allocdatabuffer.h Client data buffer allocation definitions. api/amiga_api.c Contains API initialization and deinitialization functions and data. Opening and Closing of the AmiTCP/IP socket library bases. api/amiga_api.h Description of the SocketBase structure (forinternal AmiTCP/IP use only), and some inline functions relatedto the API functionality. 74 Section 4.1 AmiTCP/IP System Manual api/amiga_libcallentry.h Included in every module which defines AmiTCP/IP socket library calls. api/amiga_libtables.c Exec library base list and AmiTCP/IP socket library function tables for MakeLibrary(). api/amiga_raf.h Compiler dependent macros for Register Argument Functions. api/apicalls.h Includes either api/apicalls_gnuc.h or api/apicalls_sasc.h. api/apicalls_gnuc.h Inline functions for internal API calls for GNUC. api/apicalls_sasc.h Inline functions for internal API calls for SASC. API Functions api/amiga_generic.c General Unix system calls related to file descriptors ported for AmiTCP/IP socket library. There are also some Amiga specific extensions to the BSD Unix system calls in this module. api/amiga_libcalls.c Inet library functions (link library in Unix system). These inet functions are provided as a part of the AmiTCP/IP socket library. api/amiga_syscalls.c Standard BSD style socket functions ported to the AmiTCP/IP socket library. api/gethostnamadr.c Functions that calls resolver in order to obtain host information from nameserver. Calls netdatabase functions if information can not be resolved. api/gethtbynamadr.h Prototypes for two functions in api/getxbyy.h. api/getxbyy.c Host (without nameserver), network, service ja protocol query functions (also a link library in unix system). api/hostbuf.h Structure definition for host queries and few minor netdb stuff. Resolver Functions api/arpa_nameser.h Information for nameserver query. api/res_comp.c Routines to translate domain names between conventional ascii and the compressed format used in queries. api/res_debug.c Functions that output debugging information3 api/res_init.h Resolver initializer function. Very simple in AmiTCP/IP implementation. api/res_mkquery.c Function that forms a domain name query in buffer. api/res_query.c Functions to generate query sequence and append domains to incomplete hostnames. api/res_send.c Function to send and receive query to and from a nameserver, respectively. api/resolv.h Resolver datatypes, defines, variables and prototypes. ________________________________ 3If RES_DEBUG defined at compile time System Manual AmiTCP/IP Section 4.2 75 4.1.6 Miscellaneous Files Makefiles GCCOPTS Compiler options forthe GCC. GNUmakefile Makefile used with GNU make in HP-UX workstations, where the source tree is maintained. SCOPTIONS Compiler options for the SAS/C 6.x Smakefile Makefile for SAS/C smake 6.x to compile the AmiTCP/IP. Revision Support bsdsocket.library_rev.rev Contains revision numberof the current version (number of the latest build). This file is updated with the BumpRev utility4. bsdsocket.library_rev.h Automaticallygenerated by BumpRev. Contains build date, version and revision strings. SAS/C 6.x GST Support all_includes.c C file for GST generation. Just includes the all_includes.h file. all_includes.h Includes all header files needed by theAmiTCP/IP, which are suitable for inclusion in a GST. Note that any headers with inline functions can not be included in a GST. Other Files conf/conf.h Static configuration information in form of preprocessor defines. Every C module must include this as the first include file. conf/rcs.h RCS header inclusion macro for GCC. InSAS/C this macro is defined in the SCOPTIONS file. protos/*/*.h Prototypes for functions in various modules. 4.2 AmiTCP/IP Initialization All more or less distinct modules of theAmiTCP/IP must be initialized before they can be used for the real work. Initialization is done in module kern/amiga_main.c, which definesfunctions init_all() and deinit_all(). The main() function calls the init_all()after it has done all needed local initializations. If init_all() failsthe deinit_all() is called to clean up. ________________________________ 4The BumpRev is supplied by Commodore. 76 Section 4.2 AmiTCP/IP System Manual 4.2.1 init _all() This function calls the initialization routines of all modules which have such. This must be done carefully in the correct partial order. There arefew general heuristics which can be applied on initialization (with respect to the ordering requirements): 1. Initialize the modules for which the initialization cannot fail. This includes semaphore initializations and such. 2. Initialize the modules which are most likely to fail, e.g. large memory allocations, modules which require recent versions of some libraries etc. 3. Initialize modules left over by rules 1 and 2. Semaphoreinitializations are first, because later steps may use them to protect against race conditions. The initialization process of the AmiTCP/IP is fully reversible. If the initialization fails in any step thedeinit _all() function can be used to collect the garbage. init_all() does the initializations in following order, returning nonzero if all steps succeed. Numbers in the parenthesis are the section and page numbers for more information, respectively: 1. malloc_init() initializes the malloc_semaphore. This is first since later steps may want to use bsd_malloc() to allocatememory (5.2.2, 95). 2. spl_init() initializes the priority level subsystem,which is used throughout the code to protect critical sections (5.3.1, 96). 3. sleep_init() initializes the sleep_semaphore and the sleep queues (5.3.2, 97). 4. readconfig() reads in and parses the command line arguments and the configuration file. This is the first phase which is expected to fail. This is done at the beginning in order to allow other initialization functions to use the configuration information given. Note that since the logging subsystem is not initialized yet, readconfig() cannot log any errors encountered (4.11, 91). 5. log_init() initializes the logging subsystem. From now on other initialization functions can log needed error messages (4.8, 89). 6. mbinit() allocates memory to be used by the protocols. This is a candidate to fail if the memory is nearly exhausted (4.5, 79). 7. timer_init() initializes the timeout module. This requires version 36 or greater of the operating system. Returns the signal mask to wait for the timeout messages (5.1, 93). 8. api_init() initializes and creates the master socketbase structure (4.10.2, 91). 9. res_init() initializes resolver structure and semaphore. System Manual AmiTCP/IP Section 4.3 77 10. sana_init() initializes the SANA-II network interface module. This returns the signal mask to be used for waiting the network related messages (4.7, 84). 11. domaininit() initializes all configured protocols. This is left at the end of the initialization, since this requires the other parts of the system to be initialized. 12. readnetdb() initializes and reads in the network data base information from ENV:AmInet/netdb (4.12, 92). 13. api_show() makes the shared library interface visible on the Exec library list (4.10.2, 91). 4.2.2 deinit _all() deinit_all() is the reverse of init_all(); it deinitializes required modules in reverse order with respect tothe initialization. If the initialization process for a module does not allocate any resources, then there is no deinitialization function for that module. The deinitialization functions called are (in this order): 1. api_hide() removes the library from the Exec librarylist, so no-one can open the library any more (4.10.2, 91). 2. sana_deinit() deinitializes the network driver module (4.7, 84). 3. api_deinit() deinitializes the API (4.10.2, 91). 4. timer_deinit() deinitializes the timer module (5.1,93). 5. mbdeinit() frees all memory used by mbufs (4.5, 79). 6. log_deinit() deinitializes the logging subsystem (4.8, 89). 4.3 The Main Module The main() function is defined in the file kern/amiga_main.c. On startup it initializes all modules by calling init _all(). After a successful initialization it first starts the AmiTCP/IP timeouts by calling timer_send(). Then it enters the event loop. AmigaOS function Wait() returns when one of the signals specified in the signal mask given as argument is received. The mask currently specifies signals for SANA-II drivers, timeouts and the break signal. When some set of these signals is received the Wait() returns and its return value, which indicates the received signals, is checked. The functions sana_poll() and timer_poll() are each called in turn if their signal was received. They each return boolean tellingif they would like to be called again before waiting again. The loop in which these functions are called is terminated either when no one of the poll functions wants to continue or when thebreak signal is received. The pollfunctions do handle only one message at a time, so that any of them should not starve. 78 Section 4.4 AmiTCP/IP System Manual When thebreak signal is received the AmiTCP/IP terminates if no library bases opened by API users are open any more. On termination all reserved resources are freed by callingdeinit _all(). 4.4 Protocol Entities One design goal was to keep the protocolentities intact. This is achieved through implementing all external dependencies of the protocol entities. Fortunately the protocol entities in BSD arehighly independent of other UNIX kernel services. For example, all dynamic memory management is done through the memory buffer5 abstraction, which means that we only had to provide the mbuf interface and the problem of memory management was solved. All protocol entities in a protocol family are defined in terms of a protocol switch structure. This structure is fully defined in the header file sys/protosw.h and [Leffler et al 1991b ]. The protocol switch structure is defined as follows: struct protosw - short pr_type; /* socket type used for */ struct domain *pr_domain; /* domain protocol a member of */ short pr_protocol; /* protocol number */ short pr_flags; /* protocol flags */ /* protocol-protocol hooks */ void (*pr_input)(); /* input to protocol (from below) */ int (*pr_output)(); /* output to protocol (from above)*/ void (*pr_ctlinput)(); /* control input (from below) */ int (*pr_ctloutput)(); /* control output (from above) */ /* user-protocol hook */ int (*pr_usrreq)(); /* user request hook */ /* utility hooks */ void (*pr_init)(); /* initialization hook */ void (*pr_fasttimo)(); /* fast timeout (200ms) */ void (*pr_slowtimo)(); /* slow timeout (500ms) */ void (*pr_drain)(); /* flush any excess space possible */ "; Note thatthe actual prototypes for the function pointers are omitted, see the file sys/protosw.h for full definition. When protocol is started the pr_init() is called first to allow the protocol to initialize all needed internal structures. Then the input process will call pr_fasttimo() and pr_slowtimo() entries periodically if defined6. The pr_drain() entry asks the protocol tofree all non-critical memory buffers in a low-memory situation. Protocolscall each other through the protocol--protocol interface. To pass a packet up in the hierarchy a protocol calls the pr_input()-entry of the protocol above it. pr_output()-entry is called when a protocol wishes to pass a packet down in the protocol hierarchy (towards network). ________________________________ 5or mbuf for short 6Member function is defined when the value of its address is not NULL. System Manual AmiTCP/IP Section 4.5 79 Protocolssend control information to each other through the pr_ctlinput() and pr_ctloutput() entries. All requests coming from the API are dispatched through the pr_usrreq() entry. 4.5 Memory Management As stated earlier, the memory managementof the protocol stack is done with memory buffers. An mbuf is a structure containinglittle amount of storage (usually 128 bytes). Some bytes of this storage are used for the header, but most of it is used to storeuser data. These small buffers are linked together to get storage for larger data. Mbufs arehighly efficient in a network protocol environment where it must be able to attach and strip protocol headers with minimum overhead and most importantly, without copying the data as doing so. When data is stored in an mbuf chain, attaching a header is achieved by simply linking the mbuf containing the header to the head of the chain. Removing a header is also done simply by removing the first mbuf or by incrementing the data pointer inside the mbuf. In general there are two types of mbufs. Ones with an packet header and ones without. An Mbuf with packet header is used as the first mbuf of every packet. This header contains extra information needed per packet. See the header file sys/mbuf.h for the mbuf header definition. Mbufs canbe chained in two dimensions. First they may be linked to form the storage for the whole message. Second these messages may be linked together so that the boundaries of messages are maintained. This second feature is mainly used by messageoriented protocols such as UDP. To gain efficiency an mbuf may have a reference to external memory page (a cluster), where a big message is copied instead of splitting it apart to many mbufs. The main advantage of this feature is avoidance of copying the data when sending it with TCP, since the clusters are shared between copies7. 4.5.1 Mbuf Functions Mbufs are accessed through set of functions which can be grouped as follows: Maintenance int mb_check_conf(void *dp, LONG newvalue) Check configurable variable whose address is dp. Return TRUE if the newvalue is acceptable value for that variable. See section 4.11 for information about the configuration. BOOL mbinit(void) ________________________________ 7TCP must keep a copy of the sent data for possible retransmissions. 80 Section 4.5 AmiTCP/IP System Manual Initialize the whole mbuf-subsystem. Allocate a chunk of mbufs and clusters (using m_alloc() and m_clalloc). Must be called before any other mbuf-related function (except that mb_check_conf() can be called anytime). void mbdeinit(void) Free all resources used by mbuf subsystem. Must be called as the last mbuf-related function in the program. BOOL m_alloc(int howmany, int canwait) Allocate howmany mbufs and place them on the mbuf free list. If canwait is true the caller can wait if memory is not readily available. BOOL m_clalloc(int ncl, int canwait); Allocate ncl mbuf clusters and place them on the cluster free list. struct mbuf *m_retry(int i, int t) Ask protocols to free space when short of memory and re-attempt to allocate an mbuf. void m_reclaim(void) Ask protocols to free space when short of memory. Allocation and Deallocation struct mbuf *m_get(int canwait, int type) Allocate an mbuf of type type. If no mbufs are available we can wait for them if canwait is M_WAIT. Initialize mbuf to contain internal data. void MGET(struct mbuf *m, int canwait, int type) This is an macro form of above. struct mbuf *m_gethdr(int canwait, int type) Allocate an mbuf of type type. If no mbufs are available we can wait for them if canwait is M_WAIT. Initialize mbuf to contain a packet header and internal data. void MGETHDR(struct mbuf *m, int canwait, int type) This is a macro form of above. struct mbuf *m_getclr(int canwait, int type) Allocate an mbuf of type type. If no mbufs are available we can wait for them if canwait is M_WAIT. If allocation succeeds the data buffer is zeroed before returning. MCLALLOC(struct mcluster *p, int canwait) A macro to allocate an mbuf cluster. The result is placed in p. System Manual AmiTCP/IP Section 4.5 81 MCLGET(struct mcluster *p, int canwait) A macro to add a cluster to a normal mbuf. M_EXT flag of the mbufis set on success. struct mbuf *m_free(struct mbuf *m) Free an mbuf. Next mbuf in the chain is returned, if any. void MFREE(struct mbuf *m, struct mbuf *n) This is an macro form of above. Successor mbuf is returned in n. MCLFREE(struct mcluster *p) A macro to free an mbuf cluster. void m_freem(struct mbuf *m) Free the whole chain of mbufs starting from m. Utility Functions struct mbuf *m_copym(struct mbuf *m, intoff0, int len, int canwait) Make a copy of an mbuf chain starting off0 bytes from the beginning of m, continuing for len bytes. If len is M_COPYALL, copy to endof mbuf. void m_copydata(struct mbuf *m, int off,int len, caddr_t cp) Copy data from an mbuf chain starting off bytes from the beginning, continuing for len bytes, into buffer cp. struct mbuf *m_prepend(struct mbuf *m, int len, int canwait) Prepend a chain of mbufs (m) with new mbuf with len bytes allocated from the first mbuf aligned on a long word boundary. void M_PREPEND(struct mbuf *m, int plen,int canwait) Macro version of above optimized for the most general cases. void M_COPY_PKTHDR(struct mbuf *to, struct mbuf *from) Macro for copying an mbuf packet header from from to to. from must have flag M_PKTHDR set, and to must be empty. void M_ALIGN(struct mbuf *m, int len) Macro to set the m data pointer of a newly--allocated mbuf (with m_get()/MGET()) to place an object of the size len at the end of the mbuf, long word aligned. void MH_ALIGN(struct mbuf *m, int len) As above, but for mbufs allocated with m_gethdr()/MGETHDR() or initialized by M_COPY_PKTHDR(). int M_LEADINGSPACE(struct mbuf *m) Compute the amount of space available before the current start of data in an mbuf. 82 Section 4.6 AmiTCP/IP System Manual int M_TRAILINGSPACE(struct mbuf *m) Compute the amount of space available after the end of data in an mbuf. void MCHTYPE(struct mbuf *m, type t) Change mbuf to a new type. void m_cat(struct mbuf *m, struct mbuf *n) Concatenate mbuf chain n to m. Both chains must be of the same type. m_adj(struct mbuf *mp, int req_len) Trim req_len bytes from the head of the mbuf chain mp if req_len is positive, else trim -- req_len bytes from the tail of the mbuf chain. struct mbuf *m_pullup(struct mbuf *n, int len) Rearrange an mbuf chain so that len bytes from the beginning of the mbuf chain n are contiguous and in the data area of the mbuf so that the data can be used as a structure. Utility Macros type t mtod(struct mbuf *m, type t) Convert mbuf pointer to a pointer to the start of the data area of the mbuf casted to type t. struct mbuf *dtom(type *x) Convert data pointer within an mbuf to mbuf pointer. 4.6 Concurrency Control The protocol implementation in the BSD net/2 is driven by network and timer interrupts and user processes calling the system functions. As the whole protocol stack is moved inside normal AmigaOS process, some modifications are in place. The processor priority levels are the main concurrency control tool of the BSD kernel. The levels defined are SPL0 (user level), SPLSOFTCLOCK, SPLNET and SPLIMP (the most privileged level). Execution at a higher level disables the execution at all lower levels. InAmiTCP/IP the concurrency control is implemented either with semaphores (when debugging) or with prevention of the task switches (Forbid()/Permit()), see section 5.3.1 on page 96 for the implementation notes. The protocol input and timeouts are driven by a single process that manages the whole protocol stack. The process sends appropriate IO requests to the timer device and the SANA-II device drivers in question. Actions are then taken as response to the returned requests. Before any protocol routines are called the priority level is raised either to SPLSOFTCLOCK or SPLNET. After the function returns the priority level is lowered back to SPL0 and the request issent back to the device driver. System Manual AmiTCP/IP Section 4.7 83 On the API side the concurrent execution of system calls is mostly prohibited, because in UNIX the system calls are atomic in the sense that there is never more than one system callin execution. In AmigaOS the shared library functions must be re-entrant so the protection must be provided by the library functions themselves. The priority at which the main process runs must be above the default value of 0 to provide enough time to process the networking protocols. On the other side there is no sense to drive the main process at greater priority than the SANA-II device drivers. 4.7 Network Device Drivers AmiTCP/IP uses standard SANA-II driversas its external network device drivers. A little glue is needed to attach a SANA-II driver into BSD net/2 code. Network Interface The BSD net/2 networking code provides aclean interface to the network device drivers. The network interface provides a consistent interface for all protocols that may be present inthe BSD Unix kernel. Each hardware device is associated with an unique network interface which may be used by one or more protocol families. The network interface is flexible enough to attach different SANA-II network device drivers into the AmiTCP/IP networking system. Common part of all network interfaces is described in [Leffler et al 1991b ]: struct ifnet - char *if_name; /* name, e.g. "en" or "lo" */ short if_unit; /* sub-unit for lower level driver */ short if_mtu; /* maximum transmission unit */ short if_flags; /* up/down, broadcast, etc. */ short if_timer; /* time 'til if_watchdog called */ int if_metric; /* routing metric (external only) */ struct ifaddr *if_addrlist; /* linked list of addresses per if */ struct ifqueue - struct mbuf *ifq_head; struct mbuf *ifq_tail; int ifq_len; int ifq_maxlen; int ifq_drops; " if_snd; /* output queue */ /* procedure handles */ int (*if_init)(); /*init routine */ int (*if_output)(); /* output routine (enqueue) */ int (*if_start)(); /* initiate output routine */ int (*if_done)(); /*output complete routine */ int (*if_ioctl)(); /* ioctl routine */ int (*if_reset)(); /* bus reset routine */ int (*if_watchdog)(); /* timer routine */ /* generic interface statistics */ int if_ipackets; /* packetsreceived on interface */ 84 Section 4.7 AmiTCP/IP System Manual int if_ierrors; /* input errors on interface */ int if_opackets; /* packetssent on interface */ int if_oerrors; /* output errorson interface */ int if_collisions; /* collisions on csma interfaces */ /* end statistics */ struct ifnet *if_next; "; Network interface for SANA-II devices are handled in the module net/if_sana.c. This is the only module aware of SANA-II devices inside the AmiTCP/IP network process. It hides most SANA-II specific details from the rest of the code. Module Initialization ULONG sana_init(void) This initialization routine is called at startup time before any interfaces have been added to system. It creates the common message port used for all SANA-II network interfaces. It also attaches the loopback device into system. It returns the signal mask of the message port, if its creation was successful. void sana_deinit(void) This routine frees all resources allocated by the SANA-II interface module. It aborts all pending IO requests, frees them, closes network device drivers and frees the corresponding network interfaces. Finally it deletes the message port. 4.7.1 SANA-II Soft Network Interface A message passing system based on the normal Exec IO requests is used to transfer packets between the AmiTCP/IP and SANA-II devices. The IO can be either synchronous or asynchronous. The SANA-II interface module has a message port, which receives all fulfilled or aborted asynchronous IO messages. A dispatch method (currently a dispatch function pointer) have been added to all asynchronously sent IOrequests. Dispatching function handles the received message in an appropriate way. A messagemay contain received packet, some buffers allocated for the sent message or an event mask. Dispatcher functions feed the received data to the protocol input queues. If needed, the protocol input routines are run. Dispatchers also free the memory allocated for the sent packets, or relays events to the higher level protocols. Because the interface for the SANA-II device driver must handle many different protocols and network adapters, it has some private data hidden from the rest of the system. The struct sana_softc network interface is defined in file net/if_sana.h: /* * SANA-II Interface descriptor * NOTE: most of the code outside will believe this to be simply * a "struct ifnet". The other information is, on the other hand, * our own business. System Manual AmiTCP/IP Section 4.7 85 */ struct sana_softc - struct ifnet ss_if; /* network-visible interface */ struct in_addr ss_ipaddr; /* copy of ip address */ ULONG ss_hwtype; /* wiretype */ UBYTE ss_hwaddr[MAXADDRSANA]; /* Generalhardware address */ struct Device *ss_dev; /* pointer todevice */ struct Unit *ss_unit; /* pointer to unit */ VOID *ss_bufmgnt; /* magic cookie for buffer mngement */ UWORD ss_reqno; /* # of requests to allocate */ struct IOIPReq *ss_reqs; /* allocated requests*/ struct MinList ss_freereq; /* free requests */ #if INET struct - UWORD reqno; /* for listening ip packets */ UWORD sent; ULONG type; " ss_ip; struct - /* for ARP */ UWORD reqno; UWORD sent; ULONG type; /* ARP packet type */ ULONG hrd; /*ARP header type */ struct arptable *table; /* ARP/IP table */ " ss_arp; #endif /* INET */ UWORD ss_rawreqno; /* for raw packets */ UWORD ss_rawsent; struct sana_softc *ss_next; char ss_name[IFNAMSIZ]; /* namelives here */ "; There isan external interface to this structure via SIOCSSANATAGS and SIOCGSANATAGS ioctls. struct ifnet *iface_find(char *name) This function initializes a network interface for given interface. It is called on a non-existent interface from ifunit(). It tries to open the appropriate SANA-II device driver, and if successful it initializes a descriptor and calls if_attach() with it. Its argument is the device driver name concatenated with a slash and unit number. This name is used by AmiTCP/IP to open appropriate unit of the SANA-II driver. The initialization routine provides the specified SANA-II network device unit with the CopyToBuf() and CopyFromBuf() function tags8. Those tags are used to copy data to and from the internal buffers of the network device. The taglist given to the device driver is defined in file net/sana2copybuff.c. After successful open iface_find() initializes the appropriate members of the new sana_softc structure. It stores the device and unit pointers, magic cookie for buffer management, hardware type, MTU ________________________________ 8For discussion for these functions, see [SANA-II 1992 add ] 86 Section 4.7 AmiTCP/IP System Manual and address length. It also searches for the hardware type specific taglist, and sets the rest of interface parameters according the taglist. Next the interface initialization routine attaches the new network interface into ifnet list with if_attach(). Then it initializes interface with if_init(). Interface Routines BOOL sana_poll(void) The AmiTCP/IP processes received messages by calling this function. It effectively hides the actual implementation from the rest of the system. This routine is called when AmiTCP/IP receives the signal allocated by sana_init(), and it returns TRUE, if itshould be called again before Wait(). sana_poll() retrieves messages from the message port, dispatches them and then runs the input queues. int sana_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, struct rtentry *rt) This function is used as the if_output() method. It tries to get a free IO request from the ss_freereq list. If no free request is available it drops the packet. It attaches the packet m0 to request, sets dispatching function to free_written_packet() and sends the request to the device driver. The raw packets to the SANA-II interface use the following variation of socket address. The addressing family of the raw packets must be AF_UNSPEC. Currently only the ARP uses the raw SANA-II packets. /* * A socket address for a generic SANA-II host */ struct sockaddr_sana2 - u_char ss2_len; u_char ss2_family; u_long ss2_type; u_char ss2_host[MAXADDRSANA]; "; void sana_ioctl(struct ifnet *ifp, int cmd, caddr_t data) This function is used as the if_ioctl() method. SANA-II devices and their respective network interfaces are configured via raw sockets by the IoctlSocket() requests. When the sana_ioctl() gets the SIOCSIFADDR request, it changes the IP address of the interface. The SIOCGIFFLAGS ioctl is used to set the parameter flags of the interface9. Special SANA-II configuration is done with SIOCSSANATAGS ioctl. It passes a tag list to the parse_sana_param_tags() function. ________________________________ 9See file sys/ioctl.h for full listof all ioctls System Manual AmiTCP/IP Section 4.7 87 void if_down(struct ifnet *ifp) This function pulls into if_ioctl() from net/if.h. if_down() marks the interface down and informs all affected network protocols about the matter. If the interface handles SANA-II device, it calls sana_down(), which handles the dirty work to put theinterface down. static void sana_run(struct sana_softc *ssc, int n, struct ifaddr *ifa) sana_run() configures the SANA-II interface and allocates the IO requests to use with the SANA-II device driver. Because the SANA-II device can be configured only once (see S2_CONFIGINTERFACE in [SANA-II 1992 add ]) the initialization routine does not configure it. Among other things the hardware address of the network adapter is set in configuration process. This function is called by the SIOGSIFADDR ioctl, which also sets the protocol address of the interface. static void sana_up(struct sana_softc *ssc) sana_up() marks interface up and enables the interface to listen the packets from the network. It sends read request with an appropriate packet type number and dispatch function to the device. static BOOL sana_down(struct sana_softc*ssc) sana_down() aborts all pending requests sent to a SANA-II device driver. static void sana_ip_read(struct sana_softc *ssc, struct IOIPReq *req) and static void sana_arp_read(struct sana_softc *ssc, struct IOIPReq *req) These dispatch functions are used to feed data from a network device to the protocol input queues. The network interface has not the input routines as members. Dispatching functions allocate mbufs for the next packet and send IO requests again to the network device. Statistics BSD Network interface contains a lot ofexcessive statistical data. Most of it is made redundant by the statistics gathered by the SANA-II driver. Because network statistics are not retrieved by looking at /dev/kmem, there is no need to gather BSD compatible statistics. A public ARexx port, named AMITCP, is set up for statistics retrieval and we can use appropriate SANA-II commands to get needed data when asked. 4.7.2 ARP The requirements for the ARP implementation for a SANA-II interface differ radically from the original implementation BSD. The original code was written exclusively for the Ethernet, which has a global addressing scheme and a fixed address length. The SANA-II ARP (in the module net/sana2arp.c) holds a separate address mapping cache for each interface. The number of entries in the cache may 88 Section 4.8 AmiTCP/IP System Manual be configured at the run time. The hardware address length varies from one interface to another. The mapping caches are hashtables with linked lists, so there is no limitations in thebucket size. ARP Table locking is done with a signal semaphore insteadof spln() functions. The ARP table is externally accessed only by IoctlSocket() calls. With the new SIOCGARPT ioctl the whole ARP cache may be read at once. There is no need to awkwardly read /dev/kmem. 4.8 Logging As everything is not predictable, programs like to inform the user about certain situations to help the user and/or maintainer to get programs work better. This is the motivation for log() and panic() functions. The fact that the file I/O routines can't be called from interrupts must be taken into account, since a program may want to inform the user even while executing at an interrupt level. Among thevery few functions of the AmigaOS which are callable from interrupts are GetMsg() and PutMsg(). These are used to implement the logging subsystem. When AmiTCP/IP has something to tell to the user, it first checks if there is any free messages available. There is only alimited number of these messages to use, since they are preallocated during initialization10. If there is no message available, a counter indicating that the message could not be deliveredis incremented. If a free message is available, the text given bycaller is printed into the buffer of the message. Then the message is sent to the private port of the NETTRACE task. The NETTRACE task is created early in the initialization of the AmiTCP/IP. This task waits for incomingmessages and when one arrives, it prints the message to the log windowand/or log file. Then message is freed by sending it back to AmiTCP/IP for reuse. If loss of log messages is detected, log() is called totell that to the user. The functions are defined as follows: int log(unsigned long level, const char*fmt, ...) This logs a message with format specified in exec.library/RawDoFmt(), similar to the printf(). It is preceded with ``'' where N is a level as defined in file sys/syslog.h. void panic(const char *fmt, ...) When this function is called, we are in BIG trouble. If task, which called this, is not AmiTCP/IP, we just halt this task and send a message to AmiTCP/IP to halt immediately and free all resources. Format is as in exec.library/RawDoFmt(). If AmiTCP/IP runs into a panic() it first patches all API functions to return an error code to the caller. Then, if the panic() was not in the context of the AmiTCP/IP it signals the AmiTCP/IP and halts. As the AmiTCP/IP receives the signal, it send a message to the log ________________________________ 10This is because memory cannotbe allocated from interrupt code. System Manual AmiTCP/IP Section 4.9 89 and signals all application programs waiting for network to take attention. As this is done, it opens an User Requester to inform the user. After the user responds, AmiTCP/IP waits for all library openers to close libraries and finally unloads itself from the memory. int printf(const char *fmt, ...) Like the normal C--library printf (with format of exec.library/RawDoFmt()) except that the printing is done using the logging mechanism. int sprintf(char *buf, const char *fmt,...) As in a normal C--library. Format is as in exec.library/RawDoFmt(). All functions (except panic()) return number of printed (or logged) characters. Initialization Routines BOOL log_init(void) This function initializes NETTRACE subsystem by opening intuition.library for opening UserRequest in the case of panic(). The the log messages are initialized to use by preallocating memory for them. Then NETTRACE is started and AmiTCP/IP waits for a signal from it. If NETTRACE success in it's initialization, then it sends a message back, which is then replied. If initialization fails, a variable is set to specific value and CTRL-F is sent to the AmiTCP/IP. If all this succeeds, the log messages are initialized and sent to logReplyPort which works as a queue for the free messages. void log_deinit(void) This works as reverse to initialization process. If NETTRACE is still running, a message is sent to it telling it to terminate. Then AmiTCP/IP waits until the message is replied. Then the memory reserved by the messages can be freed. Finally the intuition.library is closed. 4.9 ARexx Interface The ARexx port of the AmiTCP/IP is maintained by the NETTRACE task. The messages are parsed with parseline() (defined in kern/amiga_config.c). Initialization Routines ULONG rexx_init(void) This initialization routine is called at the startup time of the NETTRACE process. It opens the utility.library and the rexxsyslib.library to be used by the ARexx code and creates a public 90 Section 4.10 AmiTCP/IP System Manual ARexx message port. The signal mask of the ARexx port is returned upon a successful initialization. void rexx_deinit(void) Free all resources allocated by the ARexx interface module. First the ARexx port is removed from the system's list of message ports so that no-one is able find the port any more to send new messages. Then all pending messages are returned with error code set. Finally the ARexx port is deleted and libraries opened by rexx_init() are closed. Reply Routine BOOL rexx_poll(void) Checks if any ARexx messages has arrived and handles them one at a time. The parseline() function is used to parse and execute the given command. Returns TRUE if there might still be messages to handle, otherwise the return value is FALSE. 4.10 Application Interface Concepts 4.10.1 SocketBase -- an Extension of the Task Structure In Unix systems, where the network codeis integrated into the kernel, a process structure holds fields for per-process information of network related data. In AmiTCP/IP, where socket API is implemented as a shared library, each opener gets a newly created library base that holds data used by the AmiTCP/IP system. Each library base function makes sure that the caller is from the right Amigatask and refuses to operate if wrong task is attempting to use it (seesection 5.5 on page 100 for detailed information). 4.10.2 The System Call Semaphore and Task Priorities Currently, when program enters to some of socket library functions, it attempts to get semaphore to hold othercallers executing library code simultaneously. This is done so, since in Unix system,where this code originally runs, doesn't pre-empt process that is executing system call. In BSDSS, where ``Unix system calls'' run in user mode, system call emulation glue uses a mutex to prevent simultaneous use of that part of the server code. Although spl functions are used in NET/2 code to prevent simultaneous access of criticalsections, there may still be some sections that leave out protection if system call semaphore is removed. Unnecessary system call semaphore usageis going to be removed in later releases. Hopefully it, and the overhead it generates,becomes obsolete. The priority of the application process is raised to the same with the AmiTCP/IP, while the application executes AmiTCP/IP code. This is to prevent situations where a process witha low priority gets blocked for a long time while holding e.g. the system call semaphore, since otherwise System Manual AmiTCP/IP Section 4.11 91 all networking programs would be blockedwith it. Thisapplies to all semaphores used internally by the AmiTCP/IP, not just the system call semaphore. Initialization Routines Making application interface visible andoperative contains a few steps: call to api_init() creates the master socket library base and initializes semaphores and lists API needs. Library base is not inExec library base list yet. Routine api_show() checks first if bsdsocket.library is already in Exec list and if not, calls Exec AddLibrary() to make it visible. AmiTCP/IPcan remove socket library from the Exec list at any time, i.e. make it not visible, by calling api _hide(). No new socket bases can be opened after this call. Socket bases opened before api _hide() operate normally. If AmiTCP/IP calls api_show() again, new libraries can be opened. api_setfunctions() takes all socket library bases out of operation. It sets all function vectors in every socket base to return an error. This function is called if AmiTCP/IP panic()ed and all libraries are expected to be closed. When application interface is to be removed from system, api_deinit() is called. It waits for all opened libraries to closeand then calls expunge function to deallocate the master socket base from the memory. 4.11 Configuration Variables The configuration variable definitions are stored into a structure named cfg_variable. It is defined in kern/amiga_netdb.h as follows: /* Variable types */ /* Note: Query calls value, Set calls notify functions */ enum var_type - VAR_FUNC = 1, /* value is function pointer */ VAR_LONG, /* value is pointer to LONG */ VAR_STRP, /* value is pointer to string */ VAR_FLAG, /* LONG value is set once */ VAR_INET, /* struct sockaddr_in */ VAR_ENUM /* value is pointer to long, whose value is set according to a enumeration string in notify*/ "; typedef LONG (*var_f)(struct CSource *args, UBYTE **errstrp, struct CSource *res); typedef int (*notify_f)(void *pt, LONG new); /* Configureable variable structure */ struct cfg_variable - enum var_type type; /* type of value */ 92 Section 4.12 AmiTCP/IP System Manual WORD flags; /* see below */ const UBYTE *index; /* optional index keyword list */ void *value; /* pointer to value... */ notify_f notify; /* notification function */ "; #define boolean_enum (notify_f)"NO=FALSE=OFF=0,YES=TRUE=ON=1" /* Variable flags */ #define VF_TABLE (1<<0) /* with an index... */ #define VF_READ (1<<1) /* readable */ #define VF_WRITE (1<<2) /* writeable */ #define VF_CONF (1<<3) /* writeable only during configuration */ #define VF_RW (VF_WRITE_VF_READ) #define VF_RCONF (VF_CONF_VF_READ) #define VF_FREE (1<<8) /* free when replaced? */ The configuration file (by default AmiTCP:db/AmiTCP.config) is read with the function readconfig(). This function also parses the command line arguments. 4.12 Network Database The network database is initialized by the init _netdb() function. This function allocates the NetDataBase structure and parses the file AmiTCP:db/netdb. The NetDataBase structure is definedas follows: struct NetDataBase - struct SignalSemaphore ndb_Lock; struct MinList ndb_Hosts; struct MinList ndb_Networks; struct MinList ndb_Services; struct MinList ndb_Protocols; struct MinList ndb_NameServers; struct MinList ndb_Domains; "; This structure contains a lock and lists for the different network database entries. The lock semaphore is obtained in the shared mode for reading, and in the exclusive mode for writing. See section 2.5.1 for the information about the different entries. Chapter 5 Implementation Notes This chapter describes some points of the implementation of the AmiTCP/IP. The code that is not changedfrom the BSD net/2 -release is not reviewed. [Leffler et al 1989 ] describes the design and implementation of the BSD Unix, including the networking system. [Leffler et al 1991b ] is also very helpful. Most of the knowledge gathered during this project is gained by reading the source code itself. This chapter does not try to make that totally unnecessary. 5.1 Time outs The Unix timeout() function implements the time out needs of the Unix kernel. When kernel code calls timeout(), the functiongiven as argument will be called after the specified timeout has elapsed. In AmigaOS time outs are provided by the timer device. AmiTCP/IP sendstime out requests to the device and gets them back when the time specified has elapsed. The functions called by the time out service are: if_slowtimo() This is the time out function of the network interfaces and is defined in net/if.c. arptimer() Handles the time outs of ARP protocol (net/sana2arp.c). pfslowtimo() This is the main slow time out function for all protocols. It calls the pr_slowtimo() function of each configured protocol. The interval of this timer is 500 ms (kern/uipc_domain.c). pffasttimo() Is the corresponding function for fast (200 ms) time outs. 93 94 Section 5.1 AmiTCP/IP System Manual The request structure used by AmiTCP/IP has few fields in addition to the normal struct timerequest1. The structure is defined in kern/amiga_time.h as follows: struct timeoutRequest - struct timerequest timeout_request; /* timer.device sees only this */ struct timeval timeout_timeval; /* timeout interval */ TimerCallback_t timeout_function; /* timeout function to be called */ "; In this implementation the time out functions themselves do not call any time out services, but the functionsare called by timer_poll(), which is called by main() when there might be a message to handle (e.g. when the timer signal is received). timer_poll() checks the reply port to see if there really is a message to handle. Afterthe time out function is serviced timer_poll() sends the request back to the timer device and returns. Time outservice is implemented by files kern/amiga_time.c and kern/amiga_time.h. The functions defined are: ULONG timer_init(void) Initializes the time out subsystem by allocating the IO requests and opening the timer device. Note that AmiTCP/IP uses functions that are new to version 36 of the timer device, so the code refuses to success with Kickstart 1.3 (or lower). Returns the signal mask to wait for if successful. void timer_deinit(void) Frees all resources used by time out subsystem. void timer_send(void) Sends time out requests allocated by timer_init() tothe timer device. struct timeoutRequest *createTimeoutRequest(TimerCallback_t fun, ULONG seconds, ULONG micros) Creates a new time out request. This can be called only after successful timer_init(). void deleteTimeoutRequest(struct timeoutRequest *tr) Deletes requests created by createTimeoutRequest(). BOOL timer_poll(VOID) Checks if there are any timer requests in the reply port and if there is handles them by calling the handleTimeoutRequest(). Then it sends the request back to the timer device. void handleTimeoutRequest(struct timeoutRequest *tr) Inline function which simply calls the function specified in the time out request. ________________________________ 1See standard Amiga include file devices/timer.h System Manual AmiTCP/IP Section 5.2 95 void sendTimeoutRequest(struct timeoutRequest *tr) Inline function which sends the request to the timer device. See the files kern/amiga_main.c and kern/amiga_time.c for example of the usage. 5.2 Memory Management 5.2.1 Mbufs Mbufs are ported just as they are. Memory is allocatedin small chunks for both mbufs and clusters. The size of the cluster and the number of mbufs to allocate in one chunk are configurable variables, see section 2.4 for summary of the configurable variables in general. Note thatsince data must be copied at the SANA-II interface there is no need to use trailer protocols (whosemain gain is avoidance of that copy) and so the mbuf clusters need notbegin at page boundaries2. This fact lead to the implementation of the clusters where the size of the cluster may be arbitrary (now user configurable) and the reference count of the cluster is stored in a little header before the actual data. One noteon allocating memory for the mbufs: Since the mbuf must be perfectly aligned (i.e. 128 byte mbuf must be 128--aligned), we need to allocate one extra mbuf to be able to align the mbufs in arbitrary memory chunk returned by Exec AllocMem(). The 'canwait' argument of the mbuf functions is ignored by now, more memory will be allocated if limit of maximum memory usage is not hit. This is all right as long as the mbuf allocation functions are not called from interrupts. The only functions in the AmiTCP/IP which may get called from the interrupt code are the SANA-II callback functions m_copy_from_mbuf() and m_copy_to_mbuf()defined in file net/sana2copybuff.c. The function descriptions for the mbufs are on section 4.5. See files sys/mbuf.h and kern/uipc_mbuf.c for the actual implementation. 5.2.2 malloc() & free() Do not call the malloc() and free() functions directly! Since AmiTCP/IP is multi--threaded program these functions are not safe, since they use static data. File sys/malloc.h defines two inline functions to be used instead. They are defined as follows: static inline void * bsd_malloc(unsignedlong size, int type, int flags) This function calls malloc() to allocate memory of size size and type type. The types are defined in sys/malloc.h and are used for bookkeeping purposes. The flags may have either value M_WAITOK or M_NOWAIT. The flags are not used by this implementation, however, but are defined for portability. ________________________________ 2Well, there is no virtual memory in Amiga either. 96 Section 5.3 AmiTCP/IP System Manual static inline void bsd_free(void *addr,int type) Frees memory allocated by bsd_malloc(). The malloc() and free() are made safe by malloc_semaphore, which protects mallocs and frees from collisions. It is obtained before the actual calls to malloc() or free() and released after them. In addition to these functions sys/malloc.h defines macro versions for the most usual usages. Initialization for these functions is done by: BOOL malloc_init(void) Initializes the malloc_semaphore. This must be called early in the initialization process, since bsd_malloc() nor bsd_free() cannot be called before malloc_semaphore is initialized. 5.3 Concurrency Control 5.3.1 Processor Priority Levels In Unix systems the critical sections are mainly protected by raising the processor priority level (i.e. preventing interrupts upto a certain level). This crude way might hurt a real time operating system as the AmigaOS, so it can not be implemented assuch. Besides, the AmiTCP/IP runs as a normal user level process which has no needed privilege to alter the interrupt levels of the processor. The implementation in AmiTCP/IP is twofold; a semaphore is used in the debugging mode and task switch prevention is used in the production version. Using semaphore makes debugging easy as single stepping and tracing is possible while keeping the system alive. The semaphore adds certain overhead which is not acceptablein the production version, so the prevention of the task switches is used. When thepreprocessor symbol DEBUG is defined the spl_semaphore is used. When this semaphore is free the process is at level SPL0 (user level) and when the semaphore is allocated the process is at ``interrupt'' level (SPLSOFTCLOCK, SPLNET or SPLIMP), effectively disallowing anyone else to enter critical section. When the symbol DEBUG is not defined the functions and macrosare defined differently. They manipulate directly the Task Disable Nest Count (TDNextCnt field of the SysBase). This field is normally used by Exec functions Forbid() and Permit() which increment and decrement the value of the field, respectively. Since an assembler macro is provided byCommodore for the Forbid() function, the semantics of thefield cannot change in the future3. The semantics of the TDNestCnt is littleabused by the AmiTCP/IP, however. The value of the spl level in question is directly assigned as the value of the field. This is not visible outside of the AmiTCP/IP, since basically functions which use this field either directly or indirectly (via Forbid()/Perm* *it()) need to return the value of the field asit was when the function was called. This is also the semantics of the usageof the spl functions. ________________________________ 3If it would, then all the codeusing that official macro would break. System Manual AmiTCP/IP Section 5.3 97 The spl_semaphore is initialized by the function BOOL spl_init(void) which is called among the very first functions in the initialization process. The function spl _n(int) (defined in sys/synch.h) is used to alter the priority levels. In the non-debugging mode there are two other functions, too: spl_const(), which isused with a constant (non-zero) argument, and spl_0() which is used to switch to the level 0. In addition, a macro has been defined for each separate level for portability. The macros are as follows: spl0() switches to the normal execution level. splsoftclock() is the level on which timer eventsare executed. splnet() is the level of the network interrupts in UNIX. splimp() is the highest of the priority levels used in the networking code. For example, mbuf functions are executed at this level. These macros return the previous level which may then be set back with splx(int)-macro, which sets the level tothe level given as argument. 5.3.2 Sleeping Facilities Sleeping facility is implemented by kern/kern _synch.c. Processes sleep on a channel, which is the key used to identify sleepers. Usually this is some address which is unique to the calling process. Socket base structure for the sleeping task is linked in the sleep queue before the actual sleep is started. This is how the waking task can find the sleeper to wake up when something happens on the channel the process is sleeping on. The sleepqueue is implemented as a hash table, where the channel value is mapped to an index of a sleep queue with the hash function4 SLEEP_HASH() (defined in kern/kern_synch.c). The actual sleep is implemented by sending a time out request for the time out duration to the timer device. The sleep completes on the time out, a wakeup, a break signal or users specified signal. Note thatall critical resources (e.g. semaphores) must be freed before sleeping, since otherwise the whole networking code hangs. tsleep() does this for you. The functions which implement the sleep system are: BOOL sleep_init(void) This initializes the sleep_semaphore and the sleep queues. Thismust be called before any other functions of this module. int tsleep(struct SocketBase *p, caddr_tchan, char *wmesg, const struct timeval *time_out) ________________________________ 4Actually a macro. 98 Section 5.3 AmiTCP/IP System Manual This function is the function usually called by the processes5 and implements the sleep by using the other functions of this module. The caller goes to sleep for at most the time specified in the struct timeval argument. chan is the channel to sleep on. wmesg is a string which is marked in the socket base (p) as the reason to sleep. Currently no-one ever reads it, though. void wakeup(caddr_t chan) Wakes up any sleepers on channel chan. Searches the sleep queue for entries with key chan and wakes them up by first clearing the key (p_wchan field of the socket base structure) and then signalling the process with the signal of the time out message. The usage of the sleep queues and the p_ fields in the socket base structures are protected with sleep_semaphore, which must be obtained before even reading the sleep queues. Note that since a task in AmigaOS may get signals anytime, the sleeper checks the p_wchan field on reception of thesignal and if it is nonzero it goes to sleep again. void tsleep_send_timeout(struct SocketBase *p, const struct timeval *time_out) First ensures that the message previously sent to the timer device is back. Then sends timer device a time out request for duration specified in time_out if it is not NULL. The requestsent is allocated when the library is opened. void tsleep_abort_timeout(struct SocketBase *p, const struct timeval *time_out) Aborts the time out sent by the tsleep_send_timeout(). This function must be used when the time out must be cancelled (when the sleeper is waken up). This function just sets the timer reply port (timerPort field of the socket base) to the mode in which reception of the message does not cause any action. void tsleep_enter(struct SocketBase *p,caddr_t chan, char *wmesg) Puts the caller on to a sleep queue. int tsleep_main(struct SocketBase *p, ULONG wakemask) Waits for either time out, wakeup, break or user defined action to happen. The sigIntrMask field of the socket base structure defines which signals will cause a break. Return value of EINTR is returned if any of the signals specified in that mask are received. In addition the signals are set back with SetSignal() for the user program to be able to detect them. The wakemask argument specifies a mask for signals which should cause a return from the sleep. In such case the return value ERESTART is returned. ________________________________ 5Only WaitSelect() system calluses sleeping facilities without this function. System Manual AmiTCP/IP Section 5.4 99 On exit the process is guaranteed not to be in the sleep queues any more, but the time out remains active if it is not the reason for return. Return value on wakeup is 0 and on time out EWOULDBLOCK is returned. 5.4 Socket Library Creation Procedure Since a new socket base is created eachtime a different task opens the AmiTCP/IP socket library, the procedureis a bit more complicated than on libraries where the same library baseis returned (See [RKM Libraries 1992 ]). There is, for example, two socket library bases in use. All code discussed here is located in api/amiga _api.c. 5.4.1 Master Library Base This is the library base that is made shown by api_show() (see section 4.10.2). It is placed in Exec's librarylist. This is of type struct Library and contains information that anoutsider can read by scanning through the Exec library list. Information available is version and revision numbers and count of tasks thathave (application) library base open. Master library base has only functions ELL_Open() and ELL_Expunge(). When applications opens the socket library, the Exec calls ELL_Open(). This function creates new application socket bases and increments the reference count of open application library bases. Ifthe calling task has a socket base open already, a new socket base is not created but the reference count of task's socket base isincremented and the base pointer is returned to the caller. This feature has many useful possibilities, for example in intermediate libraries which need to manipulate the sockets of the calling task. ELL_Expunge() does (not) do one task. When it is called, it checks if there is any libraries still open or ifAmiTCP/IP lets this function execute further (in fact, currently thissecond check is sufficient since only AmiTCP/IP can close the library andit doesn't do it until all bases has been closed. The next Remove() is there forfuture reference too). Then, the memory of the master library base is deallocated and NULL is returned (no AmigaDOS seglist tofree). The SIGBREAKF _CTRL_C signal that is sent with the global varianble SB _Expunged set to TRUE notifies api_deinit() function about the fact that now all libraries are closed. 5.4.2 Application Library Bases These are the library bases that are returned to the openers of the socket library. In this base the Open() function is obsolete since all OpenLibrary() calls go through the master socket base. Exec and AmiTCP/IP generated Expunge() calls go also through the master socket base. UL_Close() is the close function for all application library bases. First it decrements the reference countof this base and returns NULL if 100 Section 5.5 AmiTCP/IP System Manual there are still references left (again,NULL informs Exec that there is no AmigaDOS seglist needed to be removed). If thereare no more references to this library base, following steps are taken to remove it from the memory: All socket descriptors still open are closed. The base is removed from the AmiTCP/IP list of open application socket bases. The timer request is deallocated. Then the library base is removed from the memoryand open count of application socket bases is decremented in the master library base. Finally, ELL_Expunge() is called if the open count reached zero and the LIBF_DELEXP flag is set (by a previous ELL_Expunge() call). 5.5 The SocketBase Structure The SocketBase structure is defined in file api/amiga_api.h as follows: struct SocketBase - struct Library libNode; /* "Global" Errno */ WORD errnoSize; /* -- now we are longword aligned -- */ UBYTE * errnoPtr; /* this points to errno */ LONG defErrno; /* Task pointer of owner task */ struct Task * thisTask; /* task priority changes (WORDS so we keep structure longword aligned) */ WORD myPri; /* task's priority just after libcall */ WORD libCallPri; /* task's priority during library call */ /* -- descriptor sets -- */ WORD dTableSize; WORD nextDToSearch; struct socket ** dTable; /* AmiTCP signal masks */ ULONG sigIntrMask; ULONG sigIOMask; ULONG sigUrgMask; /* -- these are used by tsleep()/wakeup() -- */ char * p_wmesg; queue_chain_t p_sleep_link; caddr_t p_wchan; /* event processis awaiting */ struct timerequest * tsleep_timer; struct MsgPort * timerPort; /* -- pointer to select buffer during Select() -- */ struct newselbuf * p_sb; /* -- per process fields used by various'library' functions -- */ /* buffer for inet_ntoa */ char inet_ntoa[20]; /* xxx.xxx.xxx.xxx"0 */ /* pointers for data buffers that MAY beused */ struct DataBuffer selitems; struct DataBuffer hostents; struct DataBuffer netents; struct DataBuffer protoents; struct DataBuffer servents; "; System Manual AmiTCP/IP Section 5.6 101 libNode is a normal library base structure and is used by the system. Since in this implementation each openergets a task specific library base, AmiTCP/IP links all ``user librarybases'' together using Node field of libNode. When socket library function encounters an error, it saves the value of the error to the memory location addressed by errnoPtr. errnoSize specifies the size of the variable pointed by the errnoPtr. By default errnoPtr points to the defErrno but canbe changed to point any memory location -- usually to the global errnovariable in the context of the user task. In entryof each bsdsocket.library function call, value of thisTask is compared to the task pointer of callingtask to make sure right task is calling the function. This variable is also used to find library base of some executing task. When taskis executing system calls in bsdsocket.library, its process priority is changed to the same as thatof the AmiTCP/IP task in order not to hold semaphores and block the whole network system. If some higher priority process becomes active and a lower priority task is holding some vital semaphore of the AmiTCP/IP then the precess cannot continue to run. The manipulation of the process priorities uses myPri and libCallPri fields of the socket base. dTableSize is the number of current maximum limit of socket descriptors. dTable is the descriptor table containingpointers to socket structures, i.e. sockets. nextDToSearch makes searching of free socket descriptor faster6. sigIntrMask is a task specific mask of the signals which should break the Wait() call in the tsleep_main(). Reception of such signals causes the system calls to return -1 and the error code pointed by errnoPtr to be set to EINTR. sigIOMask field specifies the signals to send when asynchronous notification is requested. Signals specified in sigUrgMask are sent when out of band data is received. These masks implement the functionality of the SIGIO and SIGURG signals of the Unix systems, respectively. All these masks can be set with the SetSocketSignals() API call. The default mask for the sigIntrMask specifies the signal for the ctrl-C, other two are zero by default. The nextgroup of variables are used by tsleep() and wakeup(). p_wmesg points to a string telling the reason why task is sleeping. p _sleep_link is used to chain library bases in the sleep queues. Waiting channel key is hold in variable p_wchan and data handling time outs in variables tsleep_timer and timerPort (more about this in section 5.3.2 on page 97). WaitSelect() inserts one selitem on each socket it wants event information of. p_sb points to a newselbuf that contains these items. Some APIfunctions in the original environment use static buffers to store their output. As a shared library cannot use static buffers (to be re-entrant), the buffers must be allocated dynamically. The SocketBase structure has space for the output buffer for the Inet_Ntoa() and pointers for other needed buffers. These buffers are allocated only when needed. ________________________________ 6Semantics of allocating lowestfree socket descriptor is preserved. 102 Section 5.6 AmiTCP/IP System Manual 5.6 The Application Program Interface Most of API code is original NET/2 codetaken from BSDSS7. BSDSS mutexes are replaced by Amiga semaphores and struct proc references are changed to references to our socket library base8. Many functions used copyin() and copyout() to copy data around. Those functions copy data between system and user space (different virtual memory mappings) in original BSD Unix system. It is also possible that those functions will fail e.g. if user tries to reference illegal memory locations. In AmiTCP/IP system copyin() and copyout()functions are replaced with bcopy(), arguments are thesame but the bcopy() never fails. Therefore some obsolete checks are removed fromthe code. 5.6.1 HowAPI Functions Are Ported Most functions in our API are ported from BSD Unix system calls. BSD Unix system call interface calls the actual function with three arguments. First is user process structure pointer. Second contains the given arguments and is locally named asuap structure. Third argument is a pointer to the return value. The function returns error value or 0 if no error occurred. The socket() function is a good example of this: socket(p, uap, retval) struct proc *p; registerstruct args - int domain; int type; int protocol; " *uap; int *retval; The system function interface maps directly to Amiga shared library. Since every task has socket library baseof its own, Unix process pointer matches to library base pointer given inregister A69 . uap argumentsare passed in registers normally. Return value is returnedin the register D0 (as any standard C compiler does). So the *retval was changed to a local variable retval and removed, whennot needed. The returned value is -1 on error, in which case the errnois also set to indicate the error (see file sys/errno.h for list of errorcodes), or retval, or 0 if no other return value is needed. To emulate Unix system call interface, each function first obtains the syscall_semaphore (why,see section 4.10.2 on page 90) and while this task is holding the semaphore, no othertask can continue to execute the ________________________________ 7BSDSS networking code is almost completely the same. 8See 5.5. 9All Amiga shared libraries expect them to be called relative to register A6 System Manual AmiTCP/IP Section 5.7 103 library code10. This means that every system call function needs to release syscall_semaphore before returning. To accomplish this, each return inside the function is changed togoto Return; and at label Return: is code that releases the syscall_semaphore11 . The default modifications were: changing file descriptor tables and pointers to socket tables and pointers,respectively, removing usage of struct fileops function pointers -- replacing them with direct socket functions, changing copyin() and copyout() functions to bcopy()s -- no more error checking here needed, and last, changing parameters on tsleep() calls. 5.6.2 APIFunctions Which Needed More Modifications IoctlSocket() (Former ioctl()): Non-socket stuff removed, and ioctl code from soo_ioctl() inserted. WaitSelect() (Former select()) usedto count remaining time out time if tsleep() returned accidentally too early. AmiTCP/IP uses the timer device for its time outs and the time out request is aborted only when it is needed again, so there is no need to send new time out requests (and to calculate their time out durations). tsleep() is broken apart into pieces so that the time out request is sent only once. CloseSocket() Decreases socket's referencecount and calls soclose() to kill the socket if it becomes zero. socket() and accept() Added initialization of so_refcnt. fdAlloc() doesn't bind fd to socket. It is done explicitly. Resolver functions used to allocate huge amounts of stack. Now memory is allocated dynamically from the head using bsd_malloc. 5.7 Changes in Functions Below API Level Functions that API functions call are mostly functions that use struct socket type arguments, possibly having some other arguments too. In most cases no modifications were needed. There was some modifications, like parameters for tsleep() call, which hadto be changed throughout the code. 5.7.1 Other Changes selscan() calls soo _select() directly, and uses socket pointer instead of file pointer. soo_select() also uses socket pointer instead of file pointer. ________________________________ 10Not all functions require obtaining syscall_semaphore so those can continue to run. 11syscall_semaphore is also freed when library function does tsleep(). 104 Section 5.8 AmiTCP/IP System Manual socreate() allows allsockets to be privileged. This means that user can obtain raw sockets and use normally privileged port numbers. sosend() uses uioread() instead of the original uiomove(). sblock() and sbwait() are called with library base pointer as the second argument. soreceive() uses uiowrite() instead of the original uiomove(). See above about the modification of call sblock() and sbwait(). sorflush() calls sblock() with base pointer argument as NULL. sosetopt() and sogetopt() : type of so_linger and so_timeo fields in socket structure is changed from short int to struct timeval. Manipulation of these data is changed accordingly. sbwait() takes socket base pointer as second argument. It is then passed to tsleep() (see section 5.3.2 on page 97). sblock() and sb_lock(): sblock() is a macro that calls sb_lock(). Both take socket base pointer as second argument. sblock() forwards that pointer directly to sb_lock() which, again, passes it to the tsleep(). 5.8 Agnet.device We used the agnet.device, an SANA-II test device, to test and develop the AmiTCP/IP network code. The usage and features of theagnet.device are described in the section 1.7.1, page 10. SANA-II is an standard network device driver interface for the Amiga (see [SANA-II 1992 add ]). It is an extension to the normal device interface, which is described in the [RKM Libs & Devs 1989 ]. Device drivers are accessed by their name fromthe system list. Drivers may be loaded dynamically from the disk, if they are not currently in the main memory. There may be several units sharing common driver code so each (network) device is specified by an unitnumber and the device driver name. We wrotethe agnet.device using the SLIP driver which Commodore has provided as the example code for SANA-IIdrivers. However, there was some problems with the supplied code. First, the SLIPdriver code obviously follows an obsolete SANA-II draft. There was some modifications in the final standard e.g. in the eventhandling and multicast addressing. The provided example code was also very fragile, it did not get compiled as such with the newer SAS C version 6. Codedepended on some features of the SAS C 5.10. For example, it always expected to find device base pointer in address registerA6. 5.8.1 IO Commands There is a detailed description of SANA-II device commands and functions in [SANA-II 1992 add ]. The following IO commands are implemented in agnet.device: System Manual AmiTCP/IP Section 5.8 105 CMD_CLEAR This standard command should return IOERR_NOCMD when issued to SANA-II device. CMD_INVALID This standard command should return IOERR_NOCMD. CMD_READ Get the next packet available of the requested packet type. The data returned (via a call to the requester-provided CopyToBuffer() function) is the Data Link Layer packet data only. Raw packets are not supported. CMD_RESET This standard command should return IOERR_NOCMD when issued to SANA-II device. CMD_START This standard command should return IOERR_NOCMD when issued to SANA-II device. CMD_STOP This standard command should return IOERR_NOCMD when issued to SANA-II device. CMD_UPDATE This standard command should return IOERR_NOCMD when issued to SANA-II device. CMD_WRITE Send packet to the network. Raw packets are not supported. Sending packet with a broadcast hardware address is not supported. S2_BROADCAST Broadcast a packet to the network. Raw packets are not supported. S2_CONFIGINTERFACE Configure the interface. The address field will be set depending on the specified hardware type. S2_DEVICEQUERY Report the statistical information about the device. S2_GETGLOBALSTATS Report accumulated statistics as defined in struct Sana2Devicestats. S2_GETSTATIONADDRESS Report the ``hardware'' address for the unit. Before the configuration, the current hardware address has all bits set. The default hardware address is not stored anywhere. S2_GETTYPESTATS Report accumulated statistics of the tracked packets. S2_OFFLINE Remove interface from service. Flush all queued IO requests. 106 Section 5.8 AmiTCP/IP System Manual S2_ONEVENT Return when specified event(s) occur(s). S2_ONLINE Put the interface back in service. This command resets the unit statistics. S2_READORPHAN If there is no pending CMD_READ request with the type of the received packet, the packet is given to first pending S2_READORPHAN request. The data returned (via a call to the requester-provided CopyToBuffer function) is the Data Link Layer packet data only. Raw packets are not supported. S2_TRACKTYPE Start tracking of the specified packet type packets. S2_UNTRACKTYPE Stop tracking of the specified packet type packets. Uninplemeted IO Commands These SANA-II device commands are not supported. CMD_FLUSH This standard command returns IOERR_NOCMD when issued to the agnet.device. S2_ADDMULTICASTADDRESS This SANA-II command is not supported. It returns IOERR_NOCMD. S2_DELMULTICASTADDRESS This SANA-II command is not supported. It returns IOERR_NOCMD. S2_GETSPECIALSTATS This SANA-II command is not fully supported. It returns an empty Sana2SpecialStat structure. This command should report accumulated driver specific statistics. This includes ethernet ``retries''. S2_MULTICAST This SANA-II command is not supported. It returns IOERR_NOCMD. 5.8.2 Initialization Procedure agnet.device must be started as a DOS process by the Run command. The dynamic loading is not yet implemented. Its own startup module, init.c, opens needed libraries, initializes device base and calls the main() function. Main function opens timer.device and initializes the ARexx port; if initialization was successful,it adds the device base to the system list. In the main loop the device task waits for three different events: user or Expunge() generated break signal(SIGF _BREAK_F), ARexx messages or user IO request messages. System Manual AmiTCP/IP Section 5.8 107 5.8.3 TheDevice Interface Functions The device interface contains 6 standardlibrary calls in the device base. The device may be opened or closed, the IO requests may be initiated or aborted and the system mayreclaim storage allocated by the device driver. These library calls are not normally executed directly by the user code but instead higher level convenience functions in the Exec. The device base library calls are made in the context of the caller, so some synchronous IO commands may be executedlike library calls without message passing overhead (quick IO). The synopsis of the functions specifies the registers where the call parameters are passed (REG(rn)). Opening an Unit An IO device is opened by the Exec function call OpenDevice(). When Exec has found the named device driver in thesystem list it calls the special DevOpen() function from the device base. DevOpen() function has following synopsis: ULONG ASM DevOpen(REG(a1) struct IOSana2Req *ios2, REG(d0) ULONG unit, REG(d1) ULONG flags) The device open function tries to allocate and initialize various resources for the specified unit if the unit does not already exist. The initialization routine InitUnit() is called; if it returns an unit structure, a private buffermanagement structure is filled from the user provided tag list. The user supplied IO request is filled with appropriate values. The promiscuous or exclusive modes are not supported. struct AgnetDevUnit *InitUnit(ULONG); The initialization routine allocates an unit structure and then calls the configuration routine ReadConfig(). If the configuration file was read and interpreted without errors the lists and locks in the unit structure is initialized. The unit is then put online and unit structure is added to the device base. BOOL ReadConfig(struct AgnetDevUnit *adu) The configuration routine attempts to read in the configuration file for the given unit. It strips the comments out of the file and provides the file as a single line to the parsing routine ParseConfig(). If there is no configuration file, the parsing routine is called with an empty line. Closing an Unit The accessed unit is closed after use with the Exec CloseDevice() function. It runs the DevClose() function from the device base. The call has the following synopsis: 108 Section 5.8 AmiTCP/IP System Manual BPTR ASM DevClose(REG(a1) struct IOSana2Req *ios2) The device close function calls the unit close function. If the device has been asked to Expunge() itself, the close function sends an appropriate signal to the device task. The device task then performs the postponed expunge function. The DevOpen() and DevClose() calls are executed while Forbid()'den unless the code explicitly Wait()'s. Initiating an IO Request The DevBeginIO function from the devicebase is called to initiate an IO command. This call is made in the context of the requesting task (task calling Exec functions DoIO() or SendIO()). The DevBeginIO() call has the following synopsis: VOID ASM DevBeginIO(REG(a1) struct IOSana2Req *ios2) The IO request is sent to the device task for dispatching and execution. Currently all IO requests are executed in the context of the device task, i.e. no quick IO is supported. Aborting an IO Request Some IO requests may be aborted before they are completed by Exec function call AbortIO(). The aborting function has thefollowing synopsis: VOID ASM DevAbortIO(REG(a1) struct IOSana2Req *ios2) Currently only the CMD_READ, S2_READORPHAN, CMD_WRITE, S2_BROADCAST, and S2_ONEVENT IO commands may be aborted. Other IO commands are executed in an atomic way and can not be aborted reliably. Expunging the Device The system may reclaim the storage allocated by the device driver by calling the DevExpunge() function. Memory reclaiming is normally done in a low memory situation or after a user requested memory flush. The expunging function has the following synopsis: VOID ASM DevExpunge(VOID) The DevExpunge() may not Wait() because it may be called from the Exec function AllocMem() protected by Forbid()/Permit() pair. The DevExpunge() function call currently signals the device task, which performs the actual expunging by calling the DoExpunge(). Each unit structure is expunged by the function ExpungeUnit(). System Manual AmiTCP/IP Section 5.8 109 5.8.4 Packet Delivery The packet sent to the pseudo network may be delayed or mutated randomly. A special structure (struct DelayRequest) stores the packet type and data during the ``transmit delay''. The delay is implemented by sending this structure as a the timer IO request to the timer device. The packet transmit functions are as follows: VOID WritePacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2) The function checks that the unit is on line and checks for the legal data length. Then the routine adds the given IO request (CMD_WRITE, S2_BROADCAST) into send queue. If there is a free delay request the SendPacket() is called immediately. VOID SendPacket(struct DelayRequest *delayed) The SendPacket() function takes an empty DelayRequest structure as its argument. First, it gets a send IO request from the send queue. The request is immediately returned if the packet is ``lost'' during transmit. This is repeated until a packet is found which is not to be lost. The packet data, type, length, transmission type and the address of the sender are then copied into the DelayRequest structure. If needed, bit errors are made into packet data. If there is specified delay for the unit, the request is sent to the timer device. After the delay the timer device returns request into the device port and it is dispatched by the ReceivePacket() function. If there is no delay, the ReceivePacket() is called immediately. VOID ReadPacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2) The function checks that unit is online, then adds the read request into an appropriate queue. VOID ReceivePacket(struct DelayRequest *delayed) The ReceivePacket() function calls the DoReceive() function on each unit the packet is destined. It then handles the DelayRequest structure back to the SendPacket() function. VOID DoReceive(struct AgnetDevUnit *adu,struct DelayRequest *delayed) The DoReceive() function tries to find a receive IO message waiting for this particular type packets. If none is found, the first S2_READORPHAN IO request is selected. The CopyBack() function sets the appropriate IO request return values and copies the packet data to the receive buffer. 5.8.5 Arexx Interface The ARexx interface is implemented by using the SimpleRexx package provided in Commodore Native Developer Update 2.0 kit. The Arexx commands executed by the agnet.device are described in section 1.7.1, page 12. 110 Section .0 AmiTCP/IP System Manual LONG ParseRexx(UBYTE *arg, UBYTE **errstr, UBYTE **result) The ARexx command string is copied into a buffer and passed to the parser function ParseRexx(). The parser allocates a DOS struct RDArgs structure for the ARexx command. This structure holds the information for the DOS parsing functions. The first keyword in the string is read and tokenized by the DOS functions ReadItem() and FindArg(). The rest of the line is parsed according this token. In the case of Query and Unit commands the unit number is read from the command line and the rest of the line is passed to the appropriate functions. LONG ParseConfig(struct AgnetDevUnit *adu, struct RDArgs *rdargs, STRPTR *errormessage) The command line stored into the RDArgs structure is parsed by the DOS function ReadArgs(). The parsed configuration information are then gathered, its legality is checked and it is stored into the unit structure. LONG ParseQuery(struct AgnetDevUnit *adu, struct RDArgs *rdargs, STRPTR *errstr, STRPTR *result) Like the ParseConfig(), ParseQuery() parses the command line by the ReadArgs(). It then fills the reply buffer by the requested configuration parameter values and then makes an ARexx string out of the buffer. This string is then returned to the ARexx process. Appendix A Autodocs for Network Applications and Utilities The AutoDoc file netutil.doc contains on-line manual pages for the network utilities and applications. Table of Contents arp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 112 ifconfig : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 114 inetd : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : :: : : : : : 117 letnet : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 119 offline : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 120 online : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 121 ping : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 122 route : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : :: : : : : : 126 111 112 Section A.1 AmiTCP/IP System Manual A.1 Network Utilities A.1.1 arp NAME Arp- address resolution display and control SYNOPSIS arp hostname arp-a netname arp-d hostname arp-s hostname address [temp] [pub] arp-f filename DESCRIPTION Arpdisplays and modifies the Internet to hardware address translation tables used by the Address Resolution Protocol. Thehardware address is a hexadecimal string with each octet separated by a colon, for instance 0:12:ff:a. The length of theaddress must be same as the address of the specified interface. OPTIONS none If no options arespecified (first form above), arp displays the current ARP entry for hostname. The hostname must either appear in the hostname database (SEE hosts), or be a DARPA Internet address expressed in Internet standard "dot notation". -a Display all current ARP entries by reading the address mapping table of the specified interface. -d If an ARP entry exists for the host called hostname, delete it. This requires super-user privileges. -s Create an ARP entry for the host called hostname with the hardware station address address. The hardware station address is given as six hexadecimal bytes separated by colons. If an ARP entry already exists for hostname,the existing entry is updated with the new information. The entry is permanent unless the word temp is given in the command. If the word pub is specified, the entry is published, which means that this system will act as an ARP server responding to requests for hostname even though the host address is not its own. -f Read file filename and set multiple entries in the ARP tables. Entries in the file should be of the form: hostname address [temp] [pub] Argument meanings are the same as for the -s option. AUTHOR Arpwas developed by the University of California, Berkeley, for the BSDUnix system. System Manual AmiTCP/IP Section A.1 113 SEE ALSO ifconfig, netif.protocols/arp, "net/if_arp.h" 114 Section A.1 AmiTCP/IP System Manual A.1.2 ifconfig NAME ifconfig - configure network interface parameters SYNOPSIS ifconfig interface address_family [address [dest_address]] [params] ifconfig interface [address_family] DESCRIPTION ifconfig is used to assign an address to a network interface and/or configure network interface parameters. ifconfig must be used at boot time to define the network address of each interface present on a machine. It can also be used at other times to redefine an interface's address or other operating parameters. PARAMETERS interface A string of the unit name. The device name (e.g. 'a2065.device') concatenated with a slash ('/') and the unit number ('11'), for example 'a2065.device/11' is a legal unit name. address_family Name of protocol on which naming scheme is based. An interface can receive transmissions in differing protocols, each of which may require separate naming schemes. Therefore,it is necessary to specify the address_family, which may affect interpretation of the remaining parameters on the command line. The only addressfamily currently supported is inet (DARPA- Internet family). address Either a host name present in the host name database, (SEE hosts), or a DARPA Internet address expressed in Internet standard "dot notation". The host number can be omitted on 10-Mbyte/second Ethernet interfaces (which use the hardware physical address), and oninterfaces other than the first. dest_address Address of destination system. Consists of either a host name present in the host name database, hosts(4), or a DARPA Internet address expressed in Internet standard "dot notation". SWITCHES Thefollowing operating parameters can be specified: up Mark an interface "up". Enables interface after an "ifconfig down." Occurs automatically when setting the addresson an interface. Setting this flag has no effectif the hardware is "down". down Mark an interface "down". When an interface is marked"down", the system will not attempt to transmit messages through that interface. If possible, the interface will be reset to disable System Manual AmiTCP/IP Section A.1 115 reception as well. This action does not automatically disable routes using the interface. arp Enable the use of Address Resolution Protocol in mappingbetween network level addresses and link-level addresses (default). -arp Disable the use of Address Resolution Protocol. metric n Set the routing metric of the interface to n, default0. The routing metric is used by the routing protocol (see gated(1m)). Higher metrics have the effectof making a route less favorable; metrics are countedas additional hops to the destination network or host. debug Enable driver-dependent debugging code. This usually turns on extra console error logging. -debug Disable driver-dependent debugging code. netmask mask (Inet only) Specify how much of the address to reserve for subdividing networks into sub-networks. mask includes the network part of the local address, and the subnetpart which is taken from the host field of the address. mask can be specified as a single hexadecimal numberwith a leading 0x, with a dot-notation Internet address, or with a pseudo- network name listed in the networktable networks(4). mask contains 1's for each bit position in the 32-bit address that are to be used for thenetwork and subnet parts, and 0's for the host part. mask should contain at least the standard networkportion, and the subnet field should be contiguous with the network portion. broadcast (Inet only) Specify the address that represents broadcasts to the network. The default broadcast addressis the address with a host part of all 1's. The command: ifconfig interface/unit with no optional command arguments supplied displays the current configuration for interface. If address_family is specified, ifconfig reports only the details specific to that address family. DIAGNOSTICS Messages indicating that the specified interface does not exist, the requested address is unknown, or the user is not privileged and tried to alter an interface's configuration. EXAMPLES 116 Section A.1 AmiTCP/IP System Manual ifconfig lo/0 127.0.0.1 This command marks internal loopback device "UP", and attach an inet address 127.0.0.1 to it. ifconfig cslip.device/0 inet 193.102.4.144 193.102.4.129 This command starts the CSLIP driver, attach an address 193.102.4.144 (our internet address) and a destination address 193.102.4.129 (the internet address of the host you are connecting) to it. ifconfig devs:network/a2065.device/0 inet 193.124.100.64 + netmask 255.255.255.192 -arp This command loads an ethernet driver for the Commodore A2065 Ethernet adapter unit 0, marks it "up", disables ARP protocol for it, attaches an inet address 193.124.100.65 to it and sets its netmask to 255.255.255.192. A bitwise logical and of netmask and address for the interface forms a subnet address, in this case 193.124.100.64. All packets aimed to hosts with same subnet address (that is hosts 193.124.100.64 - 193.124.100.127) are routed to this interface. SEE ALSO netstat, hosts, arp, "net/if.h", "net/sana2tags.h" System Manual AmiTCP/IP Section A.1 117 A.1.3 inetd NAME inetd - internet ``super-server'' TEMPLATE inetd DEBUG/S CONFIGFILE DESCRIPTION Inetd should be run when the AmiTCP/IP protocol stack is started. Inetd listens for connections on certain internet sockets. When a connection is found on one of its sockets, it decides what service the socket corresponds to, and invokes a program to service the request. After the program is finished, it continues to listen on the socket (except in some cases which will be described below). Essentially, inetd allows running one daemon to invoke several others, reducing load on the system. PARAMETERS DEBUG Turns on debugging. CONFIGFILE Specifies the configuration file name. CONFIGURATION Upon execution, inetd reads its configuration information from a configuration file which, by default, is AmiTCP:db/inetd.conf. There must be an entry for each field of the configuration file, with entries for each field separated by a tab or a space. Comments are denoted by a ``#'' at the beginning of a line or ``;'' anywhere in the line. There must be an entry for each field. The fields of the configuration file are as follows: service name socket type protocol wait/nowait user server program server program name server program arguments Theservice-name entry is the name of a valid service in the netdatabase. For ``internal'' services (discussed below), the service name must be the official name of the service. Thesocket-type should be one of ``stream'', ``dgram'', ``raw'', ``rdm'', or ``seqpacket'', depending on whether the socket is a stream, datagram, raw, reliably delivered message, or sequenced packet socket. Current system supports only stream, datagram and raw protocols. Theprotocol must be a valid protocol as given in netdatabase. Examples might be ``tcp'' or ``udp''. 118 Section A.1 AmiTCP/IP System Manual Thewait/nowait entry is useful for datagram sockets only (other sockets should have a ``nowait'' entry in this space). If a datagram server connects to its peer, freeing the socket so inetd can received further messages on the socket, it is said to be a ``multi-threaded'' server, and should use the ``nowait'' entry. For datagram servers which process all incoming datagrams on a socket and eventually time out, the server is said to be ``single-threaded'' and should use a ``wait'' entry. Comsat and talkd are both examples of the latter type ofdatagram server. Theuser entry should contain the user name of the user as whom the server should run. This field is for Unix and future compability only. Theserver-program entry should contain the pathname of the program which is to be executed by inetd when a request is found on its socket. If theserver program is resident, the path name should be suppressed. If inetd provides this service internally, this entry should be ``internal''. Theserver-program-name is CLI command name for the server process. It isshown in the printout of ``status'' command. (Task name of the server process is the service and the peer address, e.g. ``echo [192.233.15.19]''.) This and argument entry are optional. Theserver program arguments should be just as arguments normally are. Inetd provides several ``trivial'' services internally by use of routines within itself. These services are ``echo'', ``discard'', ``chargen'' (character generator), ``daytime'' (human readable time), and``time'' (machine readable time, in the form of the number of seconds since mid night, January 1, 1900). All of these services are TCPand UDP based. For details of these services, consult the appropriate RFC from the Network Information Center. Inetd rereads its configuration file when it receives the CTRL-F signal. Services may be added, deleted or modified when the configuration file is reread. HISTORY Theinetd command appeared in 4.3BSD system. SEE ALSO System Manual AmiTCP/IP Section A.1 119 A.1.4 letnet NAME Letnet - a simple TCP connection tool SYNOPSIS letnet HOSTNAME/A,PORT/A DESCRIPTION Letnet connects to the specified TCP port at the specified host. The data read from standard input is sent to the host and data received from the connection is written to the standard output. Letnet terminates upon shutdown of the socket or receiving SIGBREAKF_CTRL_C signal. ARGUMENTS HOSTNAME/A If there is no name service available, hostname maybe given in the Internet dot notation. PORT/A The port identifier is searched from the standard services (SEE ALSO netdb/services) database. A nonstandard service port may be specified in the numeric form,numbers between 1---65535 are acceptable. AUTHOR Pekka Pessi, the AmiTCP/IP Group, Helsinki University of Technology SEE ALSO netdb/services, netdb/hosts 120 Section A.1 AmiTCP/IP System Manual A.1.5 offline NAME Offline - put a SANA-II device offline TEMPLATE Offline DEV=DEVICE devicename[/unit] [UNIT unit] DESCRIPTION Offline sends the S2_OFFLINE command to the given SANA-II device driver and unit. This command is normally used to disconnect SANA-II device driver from the network adapter hardware. Device driver does notaccept any more read or write requests. EXAMPLES This command puts the SLIP offline, which frees then the serial port toyour use. OFFLINE slip.device/1 SEE ALSO Online, sana2.device/S2_OFFLINE System Manual AmiTCP/IP Section A.1 121 A.1.6 online NAME Online - put a SANA-II device online TEMPLATE Online DEV=DEVICE devicename[/unit] [UNIT unit] DESCRIPTION Online sends the S2_ONLINE command to the given SANA-II device driver andunit. The device driver restarts the network adapter hardware and accepts read and write request again. EXAMPLES This command puts the Commodore Ethernet driver online. Online a2065.device/0 SEE ALSO Offline, sana2.device/S2_ONLINE 122 Section A.1 AmiTCP/IP System Manual A.1.7 ping NAME ping - send ICMP ECHO_REQUEST packets to network hosts SYNOPSIS ping [-dfnqrvR] [-c count] [-i wait] [-l preload] [-p pattern] [-s packetsize] DESCRIPTION Ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway. ECHO_REQUEST datagrams (``pings'') have an IP and ICMP header, followed by a ``struct timeval'' and then an arbitrary number of ``pad'' bytes used to fill out the packet. The options are as follows: Other options are: -c count Stop after sending (and receiving) count ECHO_RESPONSE packets. -d Set the SO_DEBUG option on the socketbeing used. -f Flood ping. Outputs packets as fast as they come back or one hundred times per second, whichever is more. For every ECHO_REQUEST sent a period ``.'' is printed, whilefor ever ECHO_REPLY received a backspace is printed. This provides a rapid display of how many packets are being dropped. Only the super-user may use this option. This can be very hard on a network and should be used with caution. -i wait Wait wait seconds between sending each packet. Thedefault is to wait for one second between each packet. This option is incompatible with the -f option. -l preload If preload is specified, ping sends that many packets as fast as possible before falling into its normal mode of behavior. -n Numeric output only. No attempt will be made to lookup symbolic names for host addresses. -p pattern You may specify up to 16 ``pad'' bytes to fill outthe packet you send. This is useful for diagnosing data-dependent problems in a network. For example, ``-p ff'' will cause the sent packet to be filled with all ones. -q Quiet output. Nothing is displayed except the summary lines at startup time and when finished. -R Record route. Includes the RECORD_ROUTE option inthe ECHO_REQUEST packet and displays the route buffer on returned packets. Note that the IP header is only large System Manual AmiTCP/IP Section A.1 123 enough for nine such routes. Many hosts ignore or discard this option. -r Bypass the normal routing tables andsend directly to a host on an attached network. If the host is not on a directly-attached network, an error is returned. This option can be used to ping a local host through aninterface that has no route through it. -s packetsize Specifies the number of data bytes to be sent. The default is 56, which translates into 64 ICMP data bytes when combined with the 8 bytes of ICMP header data. -v Verbose output. ICMP packets other than ECHO_RESPONSE that are received are listed. When using ping for fault isolation, it should first be run on the local host, to verify that the local network interface is up and running. Then,hosts and gateways further and further away should be``pinged''. Round-trip times and packet loss statistics are computed. If duplicate packets are received, they are not included inthe packet loss calculation, although the round trip time of these packets is used in calculating the minimum/average/maximum round-trip time numbers. When the specified number of packets have been sent (and received) or if the program is terminated with a SIGINT, a brief summary is displayed. This program is intended for use in network testing, measurement and management. Because of the load it can impose on the network, it is unwise to use ping during normal operations or from automated scripts. ICMP PACKET DETAILS AnIP header without options is 20 bytes. An ICMP ECHO_REQUEST packet contains an additional 8 bytes worth of ICMP header followed byan arbitrary amount of data. When a packetsize is given, this indicated the size of this extra piece of data (the default is 56). Thus the amount of data received inside of an IP packet of type ICMP ECHO_REPLY will always be 8 bytes more than the requested data space (the ICMP header). Ifthe data space is at least eight bytes large, ping uses the first eight bytes of this space to include a timestamp which it uses in thecomputation of round trip times. If less than eight bytes of padare specified, no round trip times are given. DUPLICATE AND DAMAGED PACKETS Ping will report duplicate and damaged packets. Duplicate packets should never occur, and seem to be caused by inappropriate link-level retransmissions. Duplicates may occur in many situations andare rarely (if ever) a good sign, although the presence of low levels of duplicates may not always be cause for alarm. Damaged packets are obviously serious cause for alarm and often 124 Section A.1 AmiTCP/IP System Manual indicate broken hardware somewhere in the ping packet's path (in the network or in the hosts). TRYING DIFFERENT DATA PATTERNS The(inter)network layer should never treat packets differently depending on the data contained in the data portion. Unfortunately, data-dependent problems have been known to sneak into networks and remain undetected for long periods of time. In many cases the particular pattern that will have problems is something that doesn't have sufficient ``transitions'', such as all ones or all zeros, or a pattern right at the edge, such as almost all zeros. It isn't necessarily enough to specify a data pattern of all zeros (for example) on the command line because the pattern that is of interest isat the data link level, and the relationship between what you type and what the controllers transmit can be complicated. This means that if you have a data-dependent problem you will probably have to do a lot of testing to find it. If you are lucky, youmay manage to find a file that either can't be sent across your network or that takes much longer to transfer than other similar length files. You can then examine this file for repeated patterns that you can test using the -p option of ping. TTL DETAILS TheTTL value of an IP packet represents the maximum number of IP routers that the packet can go through before being thrown away. In current practice you can expect each router in the Internet to decrement the TTL field by exactly one. TheTCP/IP specification states that the TTL field for TCP packets should be set to 60, but many systems use smaller values (4.3 BSD uses 30, 4.2 used 15). The AmiTCP/IP uses normally TTL value 30. Themaximum possible value of this field is 255, and most systems setthe TTL field of ICMP ECHO_REQUEST packets to 255. This is why youwill find you can ``ping'' some hosts, but not reach them with telnet or ftp. Innormal operation ping prints the ttl value from the packet it re- ceives. When aremote system receives a ping packet, it can do one ofthree things with the TTL field in its response: Not change it; this is what Berkeley Unix systems did before the 4.3BSD-Tahoe release. In this case the TTL value in the received packet will be 255minus the number of routers in the round-trip path. Set it to 255; this is what AmiTCP/IP and current Berkeley Unix systems do. In this case the TTL value in the received packet will be 255 minus the number of routers in the path from the remote system to the pinging host. Set it to some othervalue. Some machines use the same value for ICMP packets that theyuse for TCP packets, for example either 30 or 60. Others may use completely wild values. System Manual AmiTCP/IP Section A.1 125 BUGS Many Hosts and Gateways ignore the RECORD_ROUTE option. Themaximum IP header length is too small for options like RECORD_ROUTE to be completely useful. There's not much that that canbe done about this, however. Flood pinging is not recommended in general, and flood pinging the broadcast address should only be done under very controlled conditions. SEE ALSO netstat, ifconfig AUTHOR Theping command originally appeared in 4.3BSD. 126 Section A.1 AmiTCP/IP System Manual A.1.8 route NAME route - manually manipulate the routing tables SYNOPSIS route [-n] [-q] [-v] command [modifiers] destination gateway DESCRIPTION Route isa program used to manually manipulate the network routing tables. Options supported by route: -n Prevent attempts to print host and networknames symbolically when reporting actions. -v (verbose) Print additional details. -q Suppress all output. Commandsaccepted by route: add Add a route. delete Delete a specific route. The destination is the destination host or network, gateway is the next-hopgateway to which packets should be addressed. Routes to a particular host are distinguished from those to a network by interpreting the Internet address associated with destination. The optionalmodifiers -net and -host force the destination to be interpreted as a network or a host, respectively. Otherwise, if the destination has a ``local address part'' of INADDR_ANY, or if the destination is the symbolic name of a network, then the route is assumed to be to a network; otherwise, it is presumed to be a route to a host. For example, 128.32 is interpreted as -host 128.0.0.32; 128.32.130 is interpreted as -host 128.32.0.130; -net 128.32 is interpreted as 128.32.0.0; and -net 128.32.130 is interpreted as 128.32.130.0. To add adefault route, give the destination as 'default'. If the route is via an interface rather than via a gateway, the -interface modifier should be specified; the gateway given is the address of this host on the common network, indicating the interface to be used for transmission. The optional -netmask qualifier is used to specify the netmask of the interface. One specifies an additional ensuing address parameter (to be interpreted as a network mask). The implicit network mask generatedcan be overridden by making sure this option follows the destination parameter. All symbolic names specified for a destination or gateway are looked up firstas a host name using gethostbyname(). If this lookup fails, System Manual AmiTCP/IP Section A.1 127 getnetbyname() is then used to interpret the name as that of a network. DIAGNOSTICS add [host_ network ] %s: gateway %s flags %x The specified route is being added to the tables. The values printed are from the routing table entry supplied in the IoctlSocket() call. If the gateway address used was not the primary address of the gateway (the first one returned by gethostbyname()), the gateway address is printed numerically as well as symbolically. delete [host _ network ] %s: gateway %s flags %x As above, but when deleting an entry. Network is unreachable An attempt to add a route failed because the gateway listed was not on a directly-connected network. The next-hop gateway must be given. not in table A delete operation was attempted for an entry which wasn't present in the tables. routing table overflow An add operation was attempted, but the system was low on resources and was unable to allocate memory to create the new entry. SEE ALSO ifconfig, protocols/routing HISTORY The routecommand appeared in 4.2BSD. Appendix B API Function Reference This appendix is a complete reference tothe functions and concepts provided by the AmiTCP/IP system. Table of Contents Standard BSD Style Socket Functions accept : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 130 bind : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 132 CloseSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 133 connect : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 134 Dup2Socket : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 136 getpeername : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 137 getsockname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 138 getsockopt : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 139 IoctlSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 142 listen : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 144 recv : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 145 recvfrom : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 145 select : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 147 send : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 150 sendto : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 150 setsockopt : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 139 shutdown : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 152 socket : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 153 WaitSelect : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 147 Other BSD Functions Related to Sockets getdtablesize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 156 Syslog : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 157 Network Data and Address Manipulation inet_addr : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :: 159 Inet_LnaOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 159 inet_lnaof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 159 128 System Manual AmiTCP/IP Section B.0 129 inet_MakeAddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :159 inet_makeaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :159 Inet_NetOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 159 inet_netof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 159 inet_network : : : : : : : : : : : : : : : : : : : : : : :: : : : : : :* * : : : : : : : 159 Inet_NtoA : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :: 159 inet_ntoa : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : : : : :: 159 Network, Protocol and Service Queries gethostbyaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 162 gethostbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 162 getnetbyaddr : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : 164 getnetbyname : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : 164 getprotobyname : : : : : : :: : : : : : : : : : : : : : : : : : : : : * *: : : : : : : 166 getprotobynumber : : : : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : : 166 getservbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 167 getservbyport : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 167 AmiTCP/IP Specific Extensions Errno : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : :: : : : : : 169 ObtainSocket : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : 170 ReleaseCopyOfSocket : :: : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : 171 ReleaseSocket : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 172 SetDTableSize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : 173 SetErrnoPtr : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 174 SetSocketSignals : : : : : : : : : : : : : : : : : :: : : : : : : : : :* * : : : : : : 175 130 Section B.1 AmiTCP/IP System Manual B.1 Standard BSD Style Socket Functions B.1.1 accept() NAME accept -accept a connection on a socket SYNOPSIS #include #include ns = accept(s, addr, addrlen) D0 D0 A0 A1 long accept(long, struct sockaddr *, long *); FUNCTION The argument s is a socket that has been created with socket(),bound to an address with bind(), and is listen- ing for connections after a listen(). accept() extracts the first connection on the queue of pending connections, creates anew socket with the same properties of s and allo- cates a new socket descriptor for the socket. If no pending connections are present on the queue, and the socket is not marked as non-blocking, accept() blocks the caller until a connection is present. If the socket is marked non-blocking and no pending connections are present on the queue, accept()returns an error as described below. The accepted socket isused to read and write data to and from the socket which connected to this one; it is not used to accept more connections. The original socket s remains open for accept- ing further connections. The argument addr is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parame- ter is determined by the domain in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr; onreturn it will contain the actual length (in bytes) of the address returned. This call is used with connection-based socket types, currently with SOCK_STREAM. It is possible to select() a socket for the purposes of doing anaccept() by selecting it for read. RETURN VALUES accept()returns a non-negative descriptor for the accepted socket onsuccess. Onfailure, it returns -1 and sets errno to indicate the error. System Manual AmiTCP/IP Section B.1 131 ERRORS EBADF - The descriptoris invalid. EINTR - The operation was interrupted by a break signal. EOPNOTSUPP - The referencedsocket is not of type SOCK_STREAM. EWOULDBLOCK - The socket is marked non-blocking and no con- nections are present to be accepted. SEE ALSO bind(), connect(), listen(), select(), SetSocketSignals(), socket() 132 Section B.1 AmiTCP/IP System Manual B.1.2 bind() NAME bind - bind a name to a socket SYNOPSIS #include #include success =bind(s, name, namelen) D0 D0 A0 D1 long bind(long, struct sockaddr *, long); FUNCTION bind() assigns a name to an unnamed socket. When a socket is created with socket(2) it exists in a name space (address family) but has no name assigned. bind() requests that the name pointed to by name be assigned to the socket. RETURN VALUES 0 - on success. -1 - on failure and sets errno to indicate the error. ERRORS EACCES - The requested address is protected, and the current user has inadequate permis- sion to access it. EADDRINUSE - The specified address is already in use. EADDRNOTAVAIL - The specified address is not available from the local machine. EBADF -s is not a valid descriptor. EINVAL - namelen is not the size of a valid address for the specified address fam- ily. The socket is already bound to an address. SEE ALSO connect(), getsockname(), listen(), socket() NOTES The rulesused in name binding vary between communication domains. System Manual AmiTCP/IP Section B.1 133 B.1.3 CloseSocket() NAME CloseSocket - delete a socket descriptor SYNOPSIS success =CloseSocket(s) D0 D0 long CloseSocket(long); FUNCTION CloseSocket() deletes a descriptor from the library base socket reference table. Ifs is the last reference to the underlying object, then the object will be deactivated and socket (see socket()), associated naming information and queued data are discarded. All sockets are automatically closed when the socket library is closed, but closing sockets as soon as possible is recommended to save system resources. RETURN VALUES 0 on success. -1 on failure and sets errnoto indicate the error. ERRORS EBADF -s is not an active socket descriptor. EINTR -linger on close was interrupted. The socket is closed, however. SEE ALSO accept(),SetSocketSignals(), shutdown(), socket(), exec.library/CloseLibrary() 134 Section B.1 AmiTCP/IP System Manual B.1.4 connect() NAME connect -initiate a connection on a socket SYNOPSIS #include #include success =connect(s, name, namelen) D0 D0 A0 D1 long connect(long, struct sockaddr *, long); FUNCTION The parameter s is a socket. If it is of type SOCK_DGRAM, then this call specifies the peer with which the socket is to be associated; this address is that to which datagrams are to be sent, and the only address from which datagrams are to bereceived. Ifit is of type SOCK_STREAM, then this call attempts to make a connection to another socket. The other socket is specified by name which is an address in the communications space of the socket. Each communications space interprets the name parameter in its own way. Gen- erally, stream sockets may successfully connect() only once; datagramsockets may use connect() multiple times to change their association. Datagram sockets may dissolve the asso- ciation by connecting to an invalid address, such as a null address. RETURN VALUES 0 on success. -1 on failure and sets errnoto indicate the error. ERRORS EADDRINUSE - The address is already in use. EADDRNOTAVAIL - The specified address is not available on the remote machine. EAFNOSUPPORT - Addresses in the specified address fam- ily cannot be used with this socket. EALREADY - The socket is non-blocking and a previ- ous connection attempt has not yet been completed. EBADF -s is not a valid descriptor. ECONNREFUSED - The attempt to connect was forcefully System Manual AmiTCP/IP Section B.1 135 rejected. The calling program should CloseSocket() the socket descriptor, and issue another socket() call to obtain a new descriptor before attempting another connect() call. EINPROGRESS - The socket is non-blocking and the con- nection cannot be completed immediately. It is possible to select() for comple- tion by selecting the socket for writ- ing. EINTR -The operation was interrupted by a break signal. EINVAL - namelen is not the size of a valid address for the specified address fam- ily. EISCONN The socket is already connected. ENETUNREACH - The network is not reachable from this host. ETIMEDOUT - Connection establishment timed out without establishing a connection. SEE ALSO accept(),CloseSocket(), connect(), getsockname(), select(), socket() 136 Section B.1 AmiTCP/IP System Manual B.1.5 Dup2Socket() NAME Dup2Socket - duplicate a socket descriptor SYNOPSIS newfd = Dup2Socket(fd1, fd2) D0 D0 D1 long Dup2Socket(long, long); DESCRIPTION Dup2Socket() duplicates an existing socket descriptor. theargument fd1 is small non-negative value that indexes thesocket on SocketBase descriptor table. The value must beless than the size of the table, which is returned by getdtablesize(). fd2 specifies the desired value of the new descriptor. If descriptor fd2 is already in use, it is first deallocated as if it were closed by CloseSocket(). If thevalue if fd2 is -1, the new descriptor used and returned isthe lowest numbered descriptor that is not currently in useby the SocketBase. RETURN VALUES Dup2Socket() returns a new descriptor on success. On failure -1is returned and errno is set to indicate the error. ERRORS EBADF fd1 or fd2 is not a valid active descriptor. EMFILE Too many descriptors are active. SEE ALSO accept(), CloseSocket(), getdtablesize(), SetDtableSize(), socket() System Manual AmiTCP/IP Section B.1 137 B.1.6 getpeername() NAME getpeername - get name of connected peer SYNOPSIS success = getpeername(s, name, namelen) D0 D0 A0 A1 long getpeername(long, struct sockaddr *, long *); FUNCTION getpeername() returns the name of the peer connected to socket s. The long pointed to by the namelen parameter should be initialized to indicate the amount of space pointed to by name. On return it contains the actual size of the name returned (in bytes). The name is truncated if the buffer provided is too small. RETURN VALUE A 0 is returned if the call succeeds, -1 if it fails. ERRORS EBADF - The argument sis not a valid descriptor. ENOBUFS - Insufficient resources were available in the system to perform the operation. ENOTCONN - The socket is not connected. SEE ALSO accept(),bind(), getsockname(), socket() 138 Section B.1 AmiTCP/IP System Manual B.1.7 getsockname() NAME getsockname - get socket name SYNOPSIS success =getsockname(s, name, namelen) D0 D0 A0 A1 long getsockname(long, struct sockaddr *, long *); FUNCTION getsockname() returns the current name for the specified socket. The namelen parameter should be initialized to indicatethe amount of space pointed to by name. On return it contains the actual size of the name returned (in bytes). DIAGNOSTICS A 0 is returned if the call succeeds, -1 if it fails. ERRORS The callsucceeds unless: EBADF s is not a valid descriptor. ENOBUFS Insufficient resources were available in the system to perform the operation. SEE ALSO bind(), getpeername(), socket() System Manual AmiTCP/IP Section B.1 139 B.1.8 getsockopt() NAME getsockopt, setsockopt - get and set options on sockets SYNOPSIS #include #include success = getsockopt(s, level, optname, optval, optlen) D0 D0 D1 D2 A0 A1 long getsockopt(long, long, long, caddr_t, long *); success = setsockopt(s, level, optname, optval, optlen) D0 D0 D1 D2 A0 D3 long setsockopt(long, long, long, caddr_t, long); FUNCTION getsockopt() and setsockopt() manipulate options associated with a socket. Options may exist at multiple protocol lev- els; theyare always present at the uppermost ``socket'' level. When manipulating socket options the level at which the option resides and the name of the option must be specified. To manipulate options at the ``socket'' level, level is specifiedas SOL_SOCKET. To manipulate options at any other level theprotocol number of the appropriate protocol con- trolling the option is supplied. For example, to indicate that an option is to be interpreted by the TCP protocol, level should be set to the protocol number of TCP. The parameters optval and optlen are used to access option values for setsockopt(). For getsockopt() they identify a buffer inwhich the value for the requested option(s) are to be returned. For getsockopt(), optlen is a value-result parameter, initially containing the size of the buffer pointed to by optval, and modified on return to indicate the actual size of the value returned. If no option value is to be supplied or returned, optval may be supplied as 0. optname and any specified options are passed uninterpreted to the appropriate protocol module for interpretation. The include file contains definitions for ``socket'' level options, described below. Options at other protocol levels vary in format and name. Most socket-level options take an int parameter for optval. For setsockopt(), the parameter should be non-zero to enable 140 Section B.1 AmiTCP/IP System Manual a booleanoption, or zero if the option is to be disabled. SO_LINGER uses a struct linger parameter, defined in , which specifies the desired state of the option and the linger interval (see below). The following options are recognized at the socket level. Except as noted, eachmay be examined with getsockopt() and set withsetsockopt(). SO_DEBUG - toggle recording of debugging information SO_REUSEADDR - toggle local address reuse SO_KEEPALIVE - toggle keep connections alive SO_DONTROUTE - toggle routing bypass for outgoing messages SO_LINGER - linger on close if data present SO_BROADCAST - toggle permission to transmit broadcast messages SO_OOBINLINE - toggle reception of out-of-band data in band SO_SNDBUF - set buffer size for output SO_RCVBUF - set buffer size for input SO_TYPE - get the type of the socket (get only) SO_ERROR - get and clear error on the socket (get only) SO_DEBUG enables debugging in the underlying protocol modules. SO_REUSEADDR indicates that the rules used in validating addresses supplied in a bind() call should allow reuse oflocal addresses. SO_KEEPALIVE enables the periodic transmission of messages on a connected socket. Should the connected party fail to respond to these messages, the con- nection is considered broken. If the process is waiting in select() when the connection is broken, select() returns true for any read or write events selected for the socket. SO_DONTROUTE indicates that outgoing messages should bypass the standard routing facilities. Instead, messages are directed to the appropriate network interface accordingto the network portion of the destination address. SO_LINGERcontrols the action taken when unsent messags are queued on socket and a CloseSocket() is performed. If the socket promises reliable delivery of data and SO_LINGER is set, the system will block the process on the close attempt until it is able to transmit the data or until it decides it is unable to deliver the information (a timeout period, in seconds, termed the linger interval, is specified in the set- sockopt() call when SO_LINGER is requested). If SO_LINGER is disabled and a CloseSocket() is issued, the System Manual AmiTCP/IP Section B.1 141 system will process the close in a manner that allows the process to continue as quickly as possible. The option SO_BROADCAST requests permission to send broad- cast datagrams on the socket. Broadcast was a privileged operationin earlier versions of the system. With protocols that support out-of-band data, the SO_OOBINLINE option requeststhat out-of-band data be placed in the normal data input queue as received; it will then be accessible with recv() orread() calls without the MSG_OOB flag. SO_SNDBUF and SO_RCVBUF are options to adjust the normal buffer sizes allocatedfor output and input buffers, respectively. The buffer size may be increased for high-volume connections, or may be decreased to limit the possible backlog of incoming data. The system places an absolute limit on these values. Finally,SO_TYPE and SO_ERROR are options used only with getsockopt(). SO_TYPE returns the type of the socket, such as SOCK_STREAM; it is useful for servers that inherit sock- ets on startup. SO_ERROR returns any pending error on the socket and clears the error status. It may be used to check for asynchronous errors on connected datagram sockets or for other asynchronous errors. RETURN VALUES 0 - on success. -1 - on failure and set errno to indicate the error. ERRORS EBADF -s is not a valid descriptor. ENOPROTOOPT - The option is unknown at the level indi- cated. SEE ALSO IoctlSocket(), socket() BUGS Several of the socket options should be handled at lower levels ofthe system. 142 Section B.1 AmiTCP/IP System Manual B.1.9 IoctlSocket() NAME IoctlSocket - control sockets SYNOPSIS #include #include value = IoctlSocket(fd, request, arg) D0 D0 D1 A0 long IoctlSocket(long, long, caddr_t); FUNCTION IoctlSocket() performs a special function on the object referred to by theopen socketdescriptor fd. Note: the setsockopt() call (seegetsockopt()) is the primary method for operating on sockets as such, rather than on the underlying protocol or network interface. For mostIoctlSocket() functions, arg is a pointer to data to be used by the function or to be filled in by the function. Other functions may ignore arg or may treat it directly as a data item; they may, for example, be passed an int value. The following requests are supported: FIOASYNC The argument is a pointer to a long. Set or clear asynchronous I/O. If the value of that long is a 1 (one) the descriptor is set for asynchronous I/O. If the value of that long is a 0 (zero) the descriptor is cleared for asynchro- nous I/O. FIOCLEX FIONCLEX Ignored, no use for close-on-exec flag in Amiga. FIOGETOWN SIOCGPGRP The argument is pointer to struct Task*. Set the value of that pointer to the Task that is receiving SIGIO or SIGURG signals for the socket referred to by the descriptor passed to IoctlSocket(). FIONBIO The argument is a pointer to a long. Set or clear non-blocking I/O. If the System Manual AmiTCP/IP Section B.1 143 value of that long is a 1 (one) the descriptor is set for non-blocking I/O. If the value of that long is a 0 (zero) the descriptor is cleared for non- blocking I/O. FIONREAD The argument is a pointer to a long. Set the value of that long to the number of immediately readable characters from the socket fd. FIOSETOWN SIOCSPGRP The argument is pointer to struct Task*, pointer to the task that will subseq- uently receive SIGIO or SIGURG signals for the socket referred to by the descriptor passed. SIOCCATMARK The argument is a pointer to a long. Set the value of that long to 1 if the read pointer for the socket referred to by the descriptor passed to IoctlSocket() points to a mark in the data stream for an out-of-band message, and to 0 if it does not point to a mark. RETURN VALUES IoctlSocket() returns 0 on success for most requests. Some specialized requests may return non-zero values on success; On failure, IoctlSocket()returns -1 and sets errno to indicate the error. ERRORS EBADF fd is not a valid descriptor. EINVAL request or arg is not valid. IoctlSocket() will also fail if the object on which the function is being performed detects an error. In this case, an error code specific to the object and the function will be returned. SEE ALSO getsockopt(), SetSocketSignals(), setsockopt() 144 Section B.1 AmiTCP/IP System Manual B.1.10 listen() NAME listen -listen for connections on a socket SYNOPSIS success =listen(s, backlog) D0 D0 D1 long listen(long, long); FUNCTION To accept connections, a socket is first created with socket(), a backlog for incoming connections is specified with listen() and then the connections are accepted with accept(). The listen() call applies only to socket of type SOCK_STREAM. The backlog parameter defines the maximum length the queue of pending connections may grow to. If a connection request arrives with the queue full the client will receive an error with an indication of ECONNREFUSED. RETURN VALUES 0 on success. -1 on failure and sets errno to indicate the error. ERRORS EBADF -s is not a valid descriptor. EOPNOTSUPP - The socketis not of a type that sup- ports listen(). SEE ALSO accept(),connect(), socket() BUGS The backlog is currently limited (silently) to 5. System Manual AmiTCP/IP Section B.1 145 B.1.11 recv() NAME recv, recvfrom, - receive a message from a socket SYNOPSIS #include #include nbytes = recv(s, buf, len, flags) D0 D0 A0 D1 D2 long recv(long, char *, long, long); nbytes = recvfrom(s, buf, len, flags, from, fromlen) D0 D0 A0 D1 D2 A1 A2 long recvfrom(long, char *, long, long, struct sockaddr *, long *); FUNCTION s is a socket created with socket(). recv() and recvfrom(), are used to receive messages from another socket. recv() may be used only on a connected socket (see connect()), while recvfrom() may be used to receive data on a socket whether it is in a connected state or not. If from is not a NULL pointer, the source address of the message is filled in. fromlen is a value-result parameter, initialized to the size of the buffer associated with from, and modified on return to indicate the actual size of the address stored there. The length of the message is returned. If a message is too long to fitin the supplied buffer, excess bytes may be discarded depending on the type of socketthe message is received from (see socket()). If no messages are available at the socket, the receive call waits for a message to arrive, unless the socket is non- blocking(see IoctlSocket()) in which case -1 is returned with theexternal variable errno set to EWOULDBLOCK. The select() call may be used to determine when more data arrive. The flagsparameter is formed by ORing one or more of the following: MSG_OOB - Read any "out-of-band" data present on the socket, rather than the regular "in-band" data. 146 Section B.1 AmiTCP/IP System Manual MSG_PEEK - "Peek" at the data present onthe socket; the data are returned, but not consumed, so that a subsequent receive operation will see the same data. RETURN VALUES These calls return the number of bytes received, or -1 if an error occurred. ERRORS EBADF -s is an invalid descriptor. EINTR -The operation was interrupted by a break signal. EWOULDBLOCK - The socket is marked non-blocking and the requested operation would block. SEE ALSO connect(), getsockopt(), IoctlSocket(), select(), send(), SetSocketSignals(), socket() System Manual AmiTCP/IP Section B.1 147 B.1.12 select() NAME select --synchronous I/O multiplexing (stub/inline function) WaitSelect -- select() with Amiga Wait() function. SYNOPSIS #include #include n = select (nfds, readfds, writefds, exceptfds, timeout) long select(long, fd_set *, fd_set *, fd_set *, struct timeval *); n = WaitSelect (nfds, readfds, writefds, exceptfds, timeout, D0 D0 A0 A1 A2 A3 sigmp) D1 long WaitSelect(long, fd_set *, fd_set *, fd_set *, struct timeval *, long *); FD_SET (fd, &fdset) FD_CLR (fd, &fdset) FD_ISSET(fd, &fdset) FD_ZERO (&fdset) long fd; fd_set fdset; DESCRIPTION select()examines the socket descriptor sets whose addresses are passed in readfds, writefds, and exceptfds to see if some of their descriptors are ready for reading, ready for writing, or have an exceptional condition pending. nfds is the number of bits to be checked in each bit mask that representa file descriptor; the descriptors from 0 through (nfds - 1) in the descriptor sets are examined. On return, select() replaces the given descriptor sets with subsets consisting of those descriptors that are ready for the requestedoperation. The total number of ready descriptors in all the sets is returned. WaitSelect() also takes a signal mask which is waited during normal select() operation. If one of these singals is recei- ved, WaitSelect() returns and has re-set the signal mask to returnthose signals that have arrived. Normal select() return values are returned. The descriptor sets are stored as bit fields in arrays of integers. The following macros are provided for manipulat- 148 Section B.1 AmiTCP/IP System Manual ing suchdescriptor sets: FD_ZERO (&fdset) initializes a descriptor set fdset to the null set. FD_SET(fd, &fdset ) includesa particular descriptor fd in fdset. FD_CLR(fd, &fdset) removes fd from fdset. FD_ISSET(fd, &fdset) is nonzero if fd is a member of fdset, zero otherwise. The behavior of these macros is undefined if a descriptor value is less than zero or greater than or equal to FD_SETSIZE, which is normally at least equal to the maximum number of descriptors supported by the system. If timeout is not a NULL pointer, it specifies a maximum interval to wait for the selection to complete. If timeout is a NULL pointer, the select blocks indefinitely. To effect a poll, the timeout argument should be a non-NULL pointer,pointing to a zero-valued timeval structure. Any of readfds, writefds, and exceptfds may be given as NULL pointersif no descriptors are of interest. Selectingtrue for reading on a socket descriptor upon which a listen() call has been performed indicates that a subse- quent accept() call on that descriptor will not block. RETURN VALUES select()returns a non-negative value on success. A positive value indicates the number of ready descriptors in the descriptor sets. 0 indicates that the time limit referred to by timeout expired or that the operation was interrupted either bya break signal or by arrival of a signal specified in *sigmp. On failure, select() returns -1, sets errno to indicatethe error, and the descriptor sets are not changed. ERRORS EBADF - One of the descriptor sets specified an invalid descriptor. EINTR - one of the signals in SIGINTR mask (see Set- SocketSignals()) is set and it was not requested in WaitSelect() call. EINVAL - A component of the pointed-to time limit is outside the acceptable range: t_sec must be between 0 and 10^8,inclusive. t_usec must be greater than or equal to 0, and less than 10^6. SEE ALSO accept(), connect(), getdtablesize(), listen(), recv(), send(), SetDTableSize(), SetSocketSignals() NOTES System Manual AmiTCP/IP Section B.1 149 Under rare circumstances, select() may indicate that a descriptor is ready for writing when in fact an attempt to write would block. This can happen if system resources necessary for a write are exhausted or otherwise unavail- able. Ifan application deems it critical that writes to a file descriptor not block, it should set the descriptor for non-blocking I/O using the FIOASYNC request to IoctlSocket(). Default system limit for open socket descriptors is currently 64. However, in order to accommodate programs which might potentially use a larger number of open files with select, it is possible to increase this size within a program by providing a larger definition of FD_SETSIZE before the inclusion of and use SetDTableSize(FD_SETSIZE) call directly after OpenLibrary(). BUGS select()should probably return the time remaining from the original timeout, if any, by modifying the time value in place. This may be implemented in future versions of the system. Thus, it is unwise to assume that the timeout pointer will be unmodified by the select() call. 150 Section B.1 AmiTCP/IP System Manual B.1.13 send() NAME send, sendto - send a message from a socket SYNOPSIS #include #include nbytes =send(s, msg, len, flags) D0 D0 A0 D1 D2 int send(int, char *, int, int); nbytes =sendto(s, msg, len, flags, to, tolen) D0 D0 A0 D1 D2 A1 D3 int send(int, char *, int, int, struct sockaddr *, int); FUNCTION s is a socket created with socket(). send() and sendto() are used totransmit a message to another socket. send() may be used only when the socket is in a connected state, while sendto()may be used at any time. The address of the target is given by to with tolen specify- ing its size. The length of the message is given by len. If the message is too long to pass atomically through the underlying protocol, then the error EMSGSIZE is returned, and the message is not transmitted. No indication of failure to deliver is implicit in a send(). Return values of -1 indicate some locally detected errors. If no buffer space is available at the socket to hold the message to be transmitted, then send() normally blocks, unless the socket has been placed in non-blocking I/O mode. The select() call may be used to determine when it is pos- sible tosend more data. The flagsparameter is formed by ORing one or more of the following: MSG_OOB - Send ``out-of-band'' data on sockets that support this notion. The underly- ing protocol must also support ``out- of-band'' data. Currently, only SOCK_STREAM sockets created in the AF_INET address family support out-of- band data. System Manual AmiTCP/IP Section B.1 151 MSG_DONTROUTE - The SO_DONTROUTE optionis turned on for the duration of the operation. This is usually used only by diagnostic or rout- ing programs. RETURN VALUES On success, these functions return the number of bytes sent. On failure, they return -1 and set errno to indicate the error. ERRORS EBADF -s is an invalid descriptor. EINTR -The operation was interrupted by a break signal. EINVAL - len is not the size of a valid address for the specified address family. EMSGSIZE - The socket requires that message be sent atomically, and the size of the message to be sent made this impossible. ENOBUFS - The system was unable to allocate an internal buffer. The operation may succeed when buffers become available. ENOBUFS - The output queue for a network interface was full. This generally indicates that the interface has stopped sending, but may be caused by transient congestion. EWOULDBLOCK - The socket is marked non-blocking and the requested operation would block. SEE ALSO connect(), getsockopt(), recv(), select(), socket() 152 Section B.1 AmiTCP/IP System Manual B.1.14 shutdown() NAME shutdown- shut down part of a full-duplex connection SYNOPSIS success =shutdown(s, how) D0 D0 D1 long shutdown(long, long); DESCRIPTION The shutdown() call causes all or part of a full-duplex con- nection on the socket associated with s to be shut down. If how is 0,then further receives will be disallowed. If how is 1, then further sends will be disallowed. If how is 2, then further sends and receives will be disallowed. RETURN VALUES 0 - on success. -1 - on failure and sets errno to indicate the error. ERRORS EBADF - s is not a valid descriptor. ENOTCONN - The specified socket is not connected. SEE ALSO connect(), socket() BUGS The how values should be defined constants. System Manual AmiTCP/IP Section B.1 153 B.1.15 socket() NAME socket -create an endpoint for communication SYNOPSIS #include #include s = socket(domain, type, protocol) D0 D0 D1 D2 long socket(long, long, long); FUNCTION socket()creates an endpoint for communication and returns a descriptor. The domain parameter specifies a communications domain within which communication will take place; this selects the protocol family which should be used. The protocol family generally is the same as the address family for the addressessupplied in later operations on the socket. These families are defined in the include file . The currently understood formats are PF_INET - (ARPA Internet protocols) The socket has the indicated type, which specifies the semanticsof communication. Currently defined types are: SOCK_STREAM SOCK_DGRAM SOCK_RAW A SOCK_STREAM type provides sequenced, reliable, two-way connection based byte streams. An out-of-band data transmission mechanism may be supported. A SOCK_DGRAM socket supports datagrams (connectionless, unreliable mes- sages of a fixed (typically small) maximum length). SOCK_RAW sockets provide access to internal network interfaces. The protocol specifies a particular protocol to be used with the socket. Normally only a single protocol exists to sup- port a particular socket type within a given protocol fam- ily. However, it is possible that many protocols may exist, in whichcase a particular protocol must be specified in this manner. The protocol number to use is particular to the "communication domain" in which communication is to take place. 154 Section B.1 AmiTCP/IP System Manual Sockets of type SOCK_STREAM are full-duplex byte streams, similar to pipes. A streamsocket must be in a connected state before any data may be sent or received on it. A con- nection to another socket is created with a connect() call. Once connected, data may be transferred using send() and recv() or their variant calls. When a session has been completeda CloseSocket() may be performed. Out-of-band data mayalso be transmitted as described in send() and receivedas described in recv(). The communications protocols used to implement a SOCK_STREAM insure that data is not lost or duplicated. If a piece of data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, then the connection is considered broken and calls will indicatean error with -1 returns and with ETIMEDOUT as the specificerror code (see Errno()). The protocols optionally keep sockets "warm" by forcing transmissions roughly every minute inthe absence of other activity. SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams to correspondents named in send() calls. Datagrams are generally received with recv(), which returns the next datagramwith its return address. The operation of sockets is controlled by socket level options. These options aredefined in the file socket.h. getsockopt() and setsockopt() are used to get and set options, respectively. RETURN VALUES socket()returns a non-negative descriptor on success. On failure,it returns -1 and sets errno to indicate the error. ERRORS EACCES - Permission to create a socket of the specified type and/or protocol is denied. EMFILE - The per-process descriptor table is full. ENOBUFS - Insufficient buffer space is available. The socket cannot be created until suf- ficient resources are freed. EPROTONOSUPPORT - The protocol type or the specified pro- tocol is not supported within this domain. System Manual AmiTCP/IP Section B.1 155 EPROTOTYPE - The protocol is the wrong type for the socket. SEE ALSO accept(),bind(), CloseSocket(), connect(), getsockname(), getsockopt(), IoctlSocket(), listen(), recv(), select(), send(), shutdown(), WaitSelect() 156 Section B.2 AmiTCP/IP System Manual B.2 Other BSD Functions Related to Sockets B.2.1 getdtablesize() NAME getdtablesize - get socket descriptor table size SYNOPSIS nfds = getdtablesize() D0 long getdtablesize(void); FUNCTION Return value of maximum number of open socket descriptors. Larger socket descriptor table can be allocated with SetDTableSize() call. SEE ALSO SetDTableSize() System Manual AmiTCP/IP Section B.2 157 B.2.2 Syslog() NAME syslog -write message to AmiTCP/IP log. SYNOPSIS #include void syslog(unsigned long level, char * format, ...); Syslog(level, format, ap) D0 A0 A1 VOID Syslog(unsigned long, const char *, va_list); FUNCTION Writes the message given as format string and arguments (printf-style) both to the log file and to the console, execpt ifthe level is LOG_EMERG, which is used by panic(), in whichcase only the log file is used since panic() generatesa User Request. The levelis selected from an ordered list: LOG_EMERG A panic condition. LOG_ALERT A condition thatshould be corrected immediately, such as a corrupted system database. LOG_CRIT Critical conditions, such as hard device errors. LOG_ERR Errors. LOG_WARNING Warning messages. LOG_NOTICE Conditions that are not error con- ditions, butthat may require spe- cial handling. LOG_INFO Informational messages. LOG_DEBUG Messages that contain information normally of use only when debugging a program. INPUTS Level - indicates the type of the message. The levels are defined in sys/syslog.h and listed above. 158 Section B.2 AmiTCP/IP System Manual format - This is a printf-style format string as defined in exec.library/RawDoFmt(). arguments- as in printf(). ap - pointer to an array of arguments. RESULT Returns no value. EXAMPLES To log a message at priority LOG_INFO, it would make the followingcall to syslog: syslog(LOG_INFO, "Connection from host %s", CallingHost); NOTES As Exec RawDoFmt() used to do formatting expects by default short (16bit long) integers you should use the `l'-modifier when appopriate. See your compiler documentation about how it passesarguments on a vararg list. This function is callable from interrupts. BUGS Because there is a limited number of internal messages used by the logging system, some log messages may get lost if a high priority task or interrupt handler sends many messages in succession. If this happens, the next log message tells the fact. SEE ALSO exec.library/RawDoFmt() System Manual AmiTCP/IP Section B.3 159 B.3 Network Data and Address Manipulation B.3.1 inet _addr() NAME inet_addr, inet_network, Inet_MakeAddr, Inet_LnaOf, Inet_NetOf, Inet_NtoA - Internet address manipulation inet_makeaddr, inet_lnaof, inet_netof, inet_ntoa-- inline/stub functions to handle structure arguments SYNOPSIS #include addr = inet_addr(cp) D0 A0 unsignedlong inet_addr(char *); net = inet_network(cp) D0 A0 unsignedlong inet_network(char *); in_addr =Inet_MakeAddr(net, lna) D0 D0 D1 unsignedlong Inet_MakeAddr(long, long); lna = Inet_LnaOf(in) D0 D0 long Inet_LnaOf(unsigned long); net = Inet_NetOf(in) D0 D0 long Inet_NetOf(unsigned long); addr = Inet_NtoA(in) DO D0 char * Inet_NtoA(unsigned long); in_addr =inet_makeaddr(net, lna) struct in_addr inet_makeaddr(long, long); lna = inet_lnaof(in) 160 Section B.3 AmiTCP/IP System Manual int inet_lnaof(struct in_addr); net = inet_netof(in) int inet_netof(struct in_addr); addr = inet_ntoa(in) char * inet_ntoa(struct in_addr); IMPLEMENTATION NOTE Return value of Inet_MakeAddr() and argument types of Inet_LnaOf(), Inet_NetOf() and Inet_NtoA() are longs instead of struct in_addr. The original behaviour is achieved by using included stub functions (lower case function names) which handle structure arguments. DESCRIPTION The routines inet_addr() and inet_network() each interpret character strings representing numbers expressed in the Internetstandard `.' notation, returning numbers suitable for use as Internet addresses and Internet network numbers, respectively. The routine inet_makeaddr() takes an Internet network number and a local network address and constructs an Internetaddress from it. The routines inet_netof() and inet_lnaof() break apart Internet host addresses, returning the network number and local network address part, respec- tively. The routine inet_ntoa() returns a pointer to a string in the base 256notation ``d.d.d.d'' described below. All Internet address are returned in network order (bytes ordered from left to right). All network numbers and local address parts are returned as machine format integer values. INTERNET ADDRESSES Values specified using the `.' notation take one of the following forms: a.b.c.d a.b.c a.b a When fourparts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address. Note: when an Internet address is viewed as a 32-bit integer quantity on little endian systems, the bytes referred to above appear as d.c.b.a. System Manual AmiTCP/IP Section B.3 161 bytes areordered from right to left. When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right most twobytes of the network address. This makes the three part address format convenient for specifying Class B net- work addresses as "128.net.host". When a two part address is supplied, the last part is inter- preted as a 24-bit quantity and placed in the right most three bytes of the network address. This makes the two part address format convenient for specifying Class A network addressesas "net.host". When onlyone part is given, the value is stored directly in the network address without any byte rearrangement. All numbers supplied as ``parts'' in a `.' notation may be decimal, octal, or hexadecimal, as specified in the C language(that is, a leading 0x or 0X implies hexadecimal; otherwise, a leading0 implies octal; otherwise, the number is interpreted as decimal). RETURN VALUE The value-1 is returned by inet_addr() and inet_network() for malformed requests. BUGS The problem of host byte ordering versus network byte order- ing is confusing. A simple way to specify Class C network addressesin a manner similar to that for Class B and Class A is needed. The return value from inet_ntoa() points to static buffer which is overwritten in each inet_ntoa() call. 162 Section B.4 AmiTCP/IP System Manual B.4 Network, Protocol and Service Queries B.4.1 gethostbyname() NAME gethostbyname, gethostbyaddr - get network host entry SYNOPSIS #include #include #include hostent =gethostbyname(name) D0 A0 struct hostent *gethostbyname(char *); hostent =gethostbyaddr(addr, len, type) D0 A0 D0 D1 struct hostent *gethostbyaddr(caddr_t, LONG, LONG); DESCRIPTION gethostbyname() and gethostbyaddr() both return a pointer to an object with the following structure containing the data received from a name server or the broken-out fields of a linein netdb configuration file. In the case of gethostbyaddr(), addr is a pointer to the binary format address of length len (not a character string) and type is an address family as defined in . struct hostent - char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ "; The members of this structure are: h_name Official name of the host. h_aliases A zero terminated array of alternate names for the host. h_addrtype The type of address being returned; currently always AF_INET. h_length The length, in bytes, of the address. System Manual AmiTCP/IP Section B.4 163 h_addr_list A pointer to a list of network addresses for the named host. Host addresses are returned in network byte order. DIAGNOSTICS A NULL pointer is returned if no matching entry was found or error occured. BUGS All information is contained in a static area so it must be copied ifit is to be saved. Only the Internet address for- mat is currently understood. SEE ALSO AmiTCP/IP configuration 164 Section B.4 AmiTCP/IP System Manual B.4.2 getnetbyname() NAME getnetbyname, getnetbyaddr - get network entry SYNOPSIS #include netent =getnetbyname(name) D0 A0 struct netent *getnetbyname(char *); netent =getnetbyaddr(net, type) D0 D0 D1 struct netent *getnetbyaddr(long, long); DESCRIPTION getnetbyname(), and getnetbyaddr() both return a pointer to an object with the following structure containing the broken-out fields of a line in netdb configuration file. struct netent - char *n_name; /* official name of net */ char **n_aliases; /* alias list */ int n_addrtype; /* net number type */ long n_net; /* net number */ "; The members of this structure are: n_name The official name of the network. n_aliases A zero terminated list of alternate names for the network. n_addrtype The type of the network number returned; currently only AF_INET. n_net The network number. Network numbers are returned in machine byte order. Network numbers are supplied in host order. Type specifies the address type to use, currently only AF_INET is supported. DIAGNOSTICS A NULL pointer is returned if no matching entry was found or error occured. System Manual AmiTCP/IP Section B.4 165 BUGS All information is contained in a static area so it must be copied ifit is to be saved. Only Internet network numbers are currently understood. SEE ALSO AmiTCP/IP configuration 166 Section B.4 AmiTCP/IP System Manual B.4.3 getprotobyname() NAME getprotobyname, getprotobynumber - get protocol entry SYNOPSIS #include protoent= getprotobyname(name) D0 A0 struct protoent *getprotobyname(char *); protoent= getprotobynumber(proto) D0 D0 struct protoent *getprotobynumber(long); DESCRIPTION getprotobyname() and getprotobynumber() both return a pointer to an object with the following structure containing the broken-out fields of a line in netdb configuration file struct protoent - char *p_name; /* official name of protocol */ char **p_aliases; /* alias list */ int p_proto; /* protocol number */ "; The members of this structure are: p_name The official name of the protocol. p_aliases A zero terminated list of alternate names for the protocol. p_proto The protocol number. DIAGNOSTICS A NULL pointer is returned if no matching entry was found or error occured. BUGS All information is contained in a static area so it must be copied if it is to be saved. Only the Internet protocols are currently understood. SEE ALSO AmiTCP/IP configuration System Manual AmiTCP/IP Section B.4 167 B.4.4 getservbyname() NAME getservbyname, getservbyport - get service entry SYNOPSIS #include servent =getservbyname(name, proto) D0 A0 A1 struct servent *getservbyname(char *, char *) servent =getservbyport(port, proto) D0 D0 A0 struct servent *getservbyport(long, char *); DESCRIPTION getservbyname() and getservbyport() both return a pointer to an object with the following structure containing the broken-out fields of a line in netdb configuration file. struct servent - char *s_name; /* official name of service */ char **s_aliases; /* alias list */ int s_port; /*port service resides at */ char *s_proto; /* protocol to use */ "; The members of this structure are: s_name The official name of the service. s_aliases A zero terminated list of alternate names for the service. s_port The port number at which the ser- vice resides. Port numbers are returned in network short byte order. s_proto The name of the protocol to use when contacting the service. The protoargument specifies the protocol for which to the sercive is to use. It is a normal C string, e.g. "tcp" or "udp". DIAGNOSTICS A NULL pointer is returned if no matching entry was found or error occured. BUGS All information is contained in a static area so it must be 168 Section B.4 AmiTCP/IP System Manual copied if it is to be saved. Expecting port numbers to fit in a 32 bit quantity is probably naive. SEE ALSO AmiTCP/IP configuration System Manual AmiTCP/IP Section B.5 169 B.5 AmiTCP/IP Specific Extensions B.5.1 Errno() NAME Errno - get error value after unsuccessful function call SYNOPSIS errno = Errno() D0 LONG Errno(VOID); FUNCTION When some function in socket library return an error conditionvalue, they also set a specific error value. This error value can be extracted by this function. RESULT Error value indicating the error on last failure of some socket function call. NOTES Return value of Errno() is not changed after successful functionso so it cannot be used to determine success of any functioncall of this library. Also, another function call to this library may change the return value of Errno() so use it right after error occurred. SEE ALSO SetErrnoPtr() 170 Section B.5 AmiTCP/IP System Manual B.5.2 ObtainSocket() NAME ObtainSocket - get a socket from AmiTCP/IP socket list SYNOPSIS s = ObtainSocket(id, domain, type, protocol) D0 D0 D1 D2 D3 LONG ObtainSocket(LONG, LONG, LONG, LONG); FUNCTION When onetask wants to give a socket to an another one, it releasesit (with a key value) to a special socket list held by AmiTCP/IP. This function requests that socket and receivesit if id and other parameters match. INPUTS id - a key value given by the socket donator. domain - see documentation of socket(). type - see documentation of socket(). protocol- see documentation of socket(). RESULT Non negative socket descriptor on success. On failure, -1 is returnedand the errno is set to indicate the error. ERRORS EMFILE - The per-process descriptor table is full. EPROTONOSUPPORT - The protocol type or the specified pro- tocol is not supported within this domain. EPROTOTYPE - The protocol is the wrong type for the socket. EWOULDBLOCK - Matching socket is not found. SEE ALSO ReleaseCopyOfSocket(), ReleaseSocket(), socket() System Manual AmiTCP/IP Section B.5 171 B.5.3 ReleaseCopyOfSocket() NAME ReleaseCopyOfSocket - copy given socket to AmiTCP/IP socket list. SYNOPSIS id = ReleaseCopyOfSocket(fd, id) D0 D0 D1 LONG ReleaseCopyOfSocket(LONG, LONG); FUNCTION Make a new reference to a given socket (pointed by its descriptor) and release it to the socket list held by AmiTCP/IP. INPUTS fd - descriptor of the socket to release. id - thekey value to identify use of this socket. It can be unique or not, depending on its value. If id value is between 0 and 65535, inclusively, it is considered nonunique and it can be used as a port number, for example. If id is greater than 65535 and less than 2^31) it must be unique in currently held sockets in AmiTCP/IP socket list, Otherwise an error will be returned and socket is not released. If id == UNIQUE_ID (defined in ) an unique id will be generated. RESULT id - -1 in case of error and the key value of the socket put in the list. Most useful when an uniqueid is generated by this routine. ERRORS EINVAL -Requested unique id is already used. ENOMEM -Needed memory couldn't be allocated. NOTE The socket descriptor is not deallocated. SEE ALSO ObtainSocket(), ReleaseSocket() 172 Section B.5 AmiTCP/IP System Manual B.5.4 ReleaseSocket() NAME ReleaseSocket - release given socket to AmiTCP/IP socket list. SYNOPSIS id = ReleaseSocket(fd, id) D0 D0 D1 LONG ReleaseSocket(LONG, LONG); FUNCTION Release the reference of given socket (via its descriptor) and movethe socket to the socket list held by AmiTCP/IP. The socket descriptor is deallocated in this procedure. INPUTS fd - descriptor of the socket to release. id - thekey value to identify use of this socket. It can be unique or not, depending on its value. If id value is between 0 and 65535, inclusively, it is considered nonunique and it can be used as a port number, for example. If id is greater than 65535 and less than 2^31) it must be unique in currently held sockets in AmiTCP/IP socket list, Otherwise an error will be returned and socket is not released. If id == UNIQUE_ID (defined in ) an unique id will be generated. RESULT id - -1 in case of error and the key value of the socket put in the list. Most useful when an uniqueid is generated by this routine. ERRORS EINVAL -Requested unique id is already used. ENOMEM -Needed memory couldn't be allocated. SEE ALSO ObtainSocket(), ReleaseCopyOfSocket() System Manual AmiTCP/IP Section B.5 173 B.5.5 SetDTableSize() NAME SetDTableSize - set socket descriptor table size of the base SYNOPSIS newsize =SetDTableSize(size) D0 D0 LONG SetDTableSize(UWORD); FUNCTION This function increases the descriptor table size inside library base so more sockets can be open at the same time. INPUT size - the new size of the desctiptor table. RESULT newsize -the new size of the descriptor table. Note that this canbe less than requested if an error occured. WARNING If the size of fd_set is not adjusted to store the increased space needed for new socket descriptors some other memory will bespilled. Change the value of FD_SETSIZE before including any socket include files and don't increase descriptor table to greater than the new value of FD_SETSIZE. SEE ALSO getdtablesize(), select() 174 Section B.5 AmiTCP/IP System Manual B.5.6 SetErrnoPtr() NAME SetErrnoPtr - set new place where the error value will be written SYNOPSIS SetErrnoPtr(ptr, size) A0 D0 VOID SetErrnoPtr(VOID *, UBYTE); FUNCTION This functions allows caller to redirect error variable inside scope of caller task. Usually this is used to make task's global variable errno as error variable. INPUTS ptr - pointer to error variable that isto be modified on every error condition on this library function. size - size of the error variable. EXAMPLE #include struct Library; struct Library * SocketBase = NULL; int main(void) - ... if ((SocketBase = OpenLibrary("bsdsocket.library", 2)) != NULL) - SetErrnoPtr(&errno, sizeof(errno)); ... " " NOTES Be sure that this new error variable exists until library base is finally closed or SetErrnoPtr() is called again for another variable. SEE ALSO Errno() System Manual AmiTCP/IP Section B.5 175 B.5.7 SetSocketSignals() NAME SetSocketSignals - inform AmiTCP/IP of INTR, IO and URG signals SYNOPSIS SetSocketSignals(sigintrmask, sigiomask, sigurgmask) D0 D1 D2 VOID SetSocketSignals(ULONG, ULONG, ULONG); FUNCTION SetSocketSignals() tells the AmiTCP/IP which signal masks corresponds UNIX SIGINT, SIGIO and SIGURG signals to be used in this implementation. sigintrmask mask is used to determine which Amiga signals interrupt blocking library calls. sigio- and sigurgmasks are sent when asynchronous notification of socket events is done and when out-of-band data arrives, respectively. Note that the supplied values write over old ones. If this functionis used and CTRL-C is still wanted to interrupt the calls (the default behaviour), the value BREAKF_CTRL_C must be explicitly given. SEE ALSO IoctlSocket(), recv(), send(), WaitSelect() Appendix C AmiTCP/IP Network Link Library This appendix describes the functions located in the net.lib. Table of Contents autoinit : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 177 autoinitd : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :* * : : : :: : : : 178 charRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 179 gethostname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : 181 lineRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :* * : : : : : : : : 182 176 System Manual AmiTCP/IP Section C.1 177 C.1 net.lib Functions C.1.1 autoinit NAME autoinit - SAS C Autoinitialization Functions SYNOPSIS _STIopenSockets() void _STIopenSockets(void) _STDcloseSockets() void _STDcloseSockets(void) FUNCTION These functions open and close the bsdsocket.library at the startup and exit of the program, respectively. For a program to use these functions, it must be linked with netlib:net.lib. Ifthe library can be opened, the _STIopenSockets() calls bsdsocket.library function SetErrnoPtr() to tell the library the address and the size of the errno variable of thecalling program. NOTES _STIopenSockets() also checks that the system version is at least 37. It puts up a requester if the bsdsocket.library isnot found or is of wrong version. Theautoinitialization and autotermination functions are features specific to the SAS C6. However, these functions canbe used with other (ANSI) C compilers, too. Example follows: "*at start of main() *" atexit(_STDcloseSockets); _STDopenSockets(); BUGS SEE ALSO bsdsocket.library/SetErrnoPtr(), SAS/C 6 User's Guide p. 145 for details of autoinitialization and autotermination functions. 178 Section C.1 AmiTCP/IP System Manual C.1.2 autoinitd NAME autoinitd - SAS C Autoinitialization Functions for Daemons SYNOPSIS void _STIopenSockets(void); void _STDcloseSockets(void); long server_socket; DESCRIPTION These are SASC autoinitialization functions for internet daemons started by inetd, Internet super-server. Upon startup, the server socket is obtained with ObtainSocket() library call. If successful, thesocket id is stored to the global variable server_socket. If the socket is not obtainable, the server_socket contains value -1. Ifthe server_socket is not valid, the server may try to accept() a newconnection and act as a stand-alone server. RESULT server_socket - positive socket id for success or -1 for failure. NOTES _STIopenSockets() also checks that the system version is at least 37. It puts up a requester if the bsdsocket.library isnot found or is of wrong version. Theautoinitialization and autotermination functions are features specific to the SAS C6. However, these functions canbe used with other (ANSI) C compilers, too. Example follows: "*at start of main() *" atexit(_STDcloseSockets); _STDopenSockets(); AUTHOR Jarno Rajahalme, Pekka Pessi, theAmiTCP/IP Group , Helsinki University of Technology, Finland. SEE ALSO serveraccept(), netutil/inetd System Manual AmiTCP/IP Section C.1 179 C.1.3 charRead NAME charRead -- read characters from socket one by one. SYNOPSIS initCharRead(rc, fd) void initCharRead(struct CharRead *, int); character = charRead(rc) intcharRead(struct CharRead *); DESCRIPTION charRead is a macro package which return characters one by one from given socket input stream. The socket where data is to be read isset by calling initCharRead(): rc is the pointer to charread structure previously allocated. fd is the (socket) descriptor where reading is to be done. charRead() returns the next character from input stream or one of the following: RC_DO_SELECT (-3) - read input buffer is returned. Do select before next call if you don't want charread to block. RC_EOF (-2) - end-of-file condition has occurred. RC_ERROR (-1) - there has been an error while filling new charread buffer. Check the value of Errno() NOTE Always use variable of type int to store return value from charRead() since the numeric value of characters returned may vary between 0 -255 (or even greater). As you may know, -3 equals 253 if of type unsigned char. EXAMPLE /* * This piece of code shows how to use charread with select() */ #include #include #include main_loop(int sock) - struct CharReadrc; fd_set readfds; int c; initCharRead(&rc, sock); 180 Section C.1 AmiTCP/IP System Manual FD_ZERO(&readfds); while(1) - FD_SET(sock, &readfds); if (select(sock + 1. &readfds, NULL, NULL, NULL)) < 0) - perror("select"); break; " if (FD_ISSET(sock, &readfds)) - while((c = charRead(&rc)) >= 0) handle_next_input_character(c); if (c == RC_EOF) break; if (c == RC_ERROR) - perror("charRead"); break; " " " " PORTABILITY Thesource file charread.h should be able to be used in UNIX programs as is. AUTHORS Tomi Ollila, theAmiTCP/IP Group , SEE ALSO lineRead(), bsdsocket.library/recv() System Manual AmiTCP/IP Section C.1 181 C.1.4 gethostname NAME gethostname -- get the name of the host SYNOPSIS error = gethostname(name, namelen); intgethostname(char *, int); FUNCTION Getthe name of the host to the buffer name of length namelen. Thename is taken from the environment variable "HOSTNAME" where it SHOULD reside. INPUTS name - Pointer to the buffer where the name should be stored. namelen - Length of the buffer name. RESULT error - 0 on success,-1 in case of an error. The global variable errno will be set to indicate the error as follows: ENOENT - The environment variable "HOSTNAME" is not found. EXAMPLE char hostname[MAXHOSTNAMELEN]; int error; error = gethostname(hostname, sizeof(hostname)); if(error < 0) exit(10); printf("My name is ""%s""."n", hostname); NOTES This function is included for source compatibility with Unix systems. TheENOENT errno value is AmiTCP/IP addition. BUGS Unlike the Unix version, this version assures that the resulting string is always NULL-terminated. SEE ALSO getenv() 182 Section C.1 AmiTCP/IP System Manual C.1.5 lineRead NAME lineRead -- read newline terminated strings from socket SYNOPSIS initLineRead(rl, fd, lftype, bufsize) void initLineRead(struct LineRead *, int, int, int); length = lineRead(rl) intlineread(struct LineRead *); DESCRIPTION lineRead() reads newline terminated strings from given descriptor very efficiently. All the options needed are set by calling initLineRead(): rl is the pointer to lineread structure previously allocated. fd is the (socket) descriptor where reading is to be done. lftype can have following 3 values: RL_LFNOTREQ - Newline terminated strings are returned unless there is no newlines left in currently buffered input. In this case remaining buffer is returned. RL_LFREQLF - If there is no newlines left in currently buffered input the remaining input datais copied at the start of buffer. Caller is informed that next call will fill the buffer (andit may block). Lines are always returned withnewline at the end unless the string is longer than whole buffer. RL_LFREQNUL - Like LF_REQLF, but remaining newline is removed. Note here that lenght is one longer that actual string length since line that has only one newline at the end would returnlength as 0 which indigate string incomplete condition. bufsize is used to tell lineread how big the receive buffer is. always put RL_BUFSIZE here since that value is used to determine thememory allocated for the buffer. This option is given to you soyou may decide to use different buffer size than the default 1024. lineRead() returns the newline terminated string in rl_line field oflineread structure. Return values of lineRead() are: 1 - RL_BUFSIZE - normal length of returned string. 0 - If zero is returned just after select(), end-of-file condition has occurred. Otherwise string is not completed yet. Make sure you call select() (or use non- blocking IO) if you don't want next call System Manual AmiTCP/IP Section C.1 183 to block. -1 - if rl_Line field of lineread structure is NULL, it indicates error condition. If rl_Line points to start of string buffer, input string has been longer than buffer. In this case rl_Line points to zero terminated string of length RL_BUFSIZE. Youmay modify the zero terminated string returned by lineRead() in anyway, but memory around the string is private lineread memory. EXAMPLE /* * The following code shows how to use lineread with select() */ #ifdef USE_LOW_MEMORY_BUFFER #define RL_BUFSIZE 256 #endif #include #ifdef AMIGA #include #endif #include #define NULL 0 ... main_loop(int sock) - struct LineRead* rl; int length; fd_set reafdfs; if (rl = (struct LineRead *)AllocMem(sizeof (*rl), 0)) - initLineRead(rl, sock, LF_REQLF, RL_BUFSIZE); FD_ZERO(&readfds); while(1) - FD_SET(sock, &readfds); if (select(sock + 1, &readfds, NULL, NULL, NULL)) < 0) - perror("select"); break; " if (FD_ISSET(sock, &readfds)) if ((length = lineRead(rl)) == 0) /* EOF */ break; do - if (length > 0) 184 Section C.1 AmiTCP/IP System Manual write(1, rl->rl_Line, length); /* stdout. write() for */ /* speed demonstration*/ else - /* length == -1 */ if (rl->rl_Line == NULL); - perror("lineRead"); break; " else - fprintf(stderr, "lineread input buffer overflow!"n"); write(1, rl->rl_Line, RL_BUFSIZE); write(1, ""n", 1); " " " while ((length = lineRead(rl)) != 0); /* 0 -> doselect() */ " FreeMem(rl, sizeof (*rl); " else fprintf("AllocMem: Out Of memory"n"); " PORTABILITY Thesource modules lineread.c and lineread.h should compile inUNIX machines as is. AUTHORS Tomi Ollila, theAmiTCP/IP Group , SEE ALSO readChar(), bsdsocket.library/recv() Appendix D Protocols and Network Interfaces The AutoDoc file protocol.doc contains on-line manual pages for protocols and network interfaces. Table of Contents arp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 186 icmp : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 189 if : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 190 inet : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :* * : : : : : : : : : 193 ip : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 196 lo : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 198 routing : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : 199 tcp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 201 udp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : * *: : : : : : : : : : 203 185 186 Section D.1 AmiTCP/IP System Manual D.1 Protocols and Network Interfaces D.1.1 arp NAME arp- Address Resolution Protocol CONFIG AnySANA-II device driver using ARP SYNOPSIS #include #include #include s =socket(AF_INET, SOCK_DGRAM, 0); DESCRIPTION ARPis a protocol used to dynamically map between Internet Protocol (IP) and hardware addresses. It can be used by most theSANA-II network interface drivers. The current implementation supports only Internet Protocol (and is tested only with Ethernet). However, ARP is not limited to only that combination. ARPcaches IP-to-hardware address mappings. When an interface requests a mapping for an address not in the cache, ARP queues themessage which requires the mapping and broadcasts a message on the associated network requesting the address mapping. If a response is provided, the new mapping is cached andany pending message is transmitted. ARP will queue at most onepacket while waiting for a mapping request to be responded to;only the most recently transmitted packet is kept. Theaddress mapping caches are separate for each interface. The amount of mappings in the cache may be specified with an IoctlSocket() request. Tofacilitate communications with systems which do not use ARP, IoctlSocket() requests are provided to enter and delete entries inthe IP-to-Ethernet tables. USAGE #include #include #include #include struct arpreq arpreq; IoctlSocket(s, SIOCSARP, (caddr_t)&arpreq); IoctlSocket(s, SIOCGARP, (caddr_t)&arpreq); IoctlSocket(s, SIOCDARP, (caddr_t)&arpreq); These three IoctlSocket()s take the same structure as an argument. System Manual AmiTCP/IP Section D.1 187 SIOCSARP sets an ARP entry, SIOCGARP gets an ARP entry, and SIOCDARP deletes an ARP entry. These IoctlSocket() requests may be applied to anysocket descriptor (s). The arpreq structure contains: /*Maximum number of octets in protocol/hw address */ #define MAXADDRARP 16 /* * ARP ioctl request. */ struct arpreq - struct sockaddr arp_pa; /* protocol address */ struct - /* hardware address */ u_char sa_len; /* actual length + 2 */ u_char sa_family; char sa_data[MAXADDRARP]; " arp_ha; int arp_flags; /* flags */ "; /* arp_flags andat_flags field values */ #define ATF_INUSE 0x01 /* entry in use */ #define ATF_COM 0x02 /* completed entry */ #define ATF_PERM 0x04 /* permanent entry */ #define ATF_PUBL 0x08 /* publish entry */ Theinterface whose ARP table is manipulated is specified by arp_pa sockaddr. The address family for the arp_pa sockaddr must be AF_INET; for the arp_ha sockaddr it must be AF_UNSPEC. Thelength of arp_ha must match the length of used hardware address. Maximum length for the hardware address is MAXADDRARP bytes. The only flag bits which may be written are ATF_PERM andATF_PUBL. ATF_PERM makes the entry permanent if the IoctlSocket() call succeeds. ATF_PUBL specifies that the ARP code should respond to ARP requests for the indicated host coming from other machines. This allows a host to act as an ARPserver which may be useful in convincing an ARP-only machine to talk to a non-ARP machine. UNSUPPORTED IN AmiTCP/IP AmiTCP/IP EXTENSIONS There is an extension to the standard BSD4.4 ARP ioctl interface to access the contents of the whole ARP mapping cache. (In the BSD4.4 thestatic ARP table is accessed via the /dev/kmem.) The SIOCGARPT ioctl takes the following arptabreq structure as an argument: /* * An AmiTCP/IP specific ARP table ioctl request */ struct arptabreq - struct arpreq atr_arpreq; /* To identify the interface */ long atr_size; /* # of elements in atr_table */ long atr_inuse; /* # of elements in use */ 188 Section D.1 AmiTCP/IP System Manual struct arpreq *atr_table; "; Theatr_arpreq specifies the used interface. The hardware address forthe interface is returned in the arp_ha field of atr_arpreq structure. TheSIOCGARPT ioctl reads at most atr_size entries from the cache into the user supplied buffer atr_table, if it is not NULL. Actual amount of returned entries is returned in atr_size. The current amount of cached mappings is returned in the atr_inuse. TheSIOCGARPT ioctl has following usage: struct arpreq cache[N]; struct arptabreq arptab = - N, 0, cache "; IoctlSocket(s, SIOCGARPT, (caddr_t)&arptabreq); DIAGNOSTICS ARPwatches passively for hosts impersonating the local host (that is, a host which responds to an ARP mapping request forthe local host's address). "duplicate IP address a.b.c.d!!" "sent from hardware address: %x:%x:...:%x:%x" ARP has discovered another host on the local network which responds to mapping requests for its own Internet address. BUGS TheARP is tested only with Ethernet. Other network hardware may require special ifconfig configuration. SEE ALSO inet, netutil/arp, netutil/ifconfig, Plummer, Dave, ``An Ethernet Address Resolution Protocol -or- ConvertingNetwork Protocol Addresses to 48.bit Ether- netAddresses for Transmission on Ethernet Hardware,'' RFC 826, Network Information Center, SRI International, Menlo Park, Calif., November 1982. (Sun 800-1059-10) System Manual AmiTCP/IP Section D.1 189 D.1.2 icmp NAME icmp - Internet Control Message Protocol SYNOPSIS #include #include int socket(AF_INET, SOCK_RAW, proto) DESCRIPTION ICMP is the error and control message protocol used by IP and the Internet protocol family. It may be accessed through a ``raw socket'' for network monitoring and diagnostic functions. The proto parameter to the socket call to create an ICMP socket is obtained from getprotobyname(). ICMP sockets are connectionless, and are normally used with the sendto() and recvfrom() calls, though the connect() call may also be used to fix the destination for future packets (in which case the recv() and send() socket library calls maybe used). Outgoing packets automatically have an IP header prepended to them (based on the destination address). Incoming packets are received with the IP header and options intact. DIAGNOSTICS A socket operation may fail with one of the following errors returned: [EISCONN] when trying to establish a connection ona socket which already has one, orwhen trying to send a datagram with the destination address specified and the socket is already connected; [ENOTCONN] when trying tosend a datagram, but no destination address is specified, andthe socket hasn't been connected; [ENOBUFS] when the system runs out of memory for aninternal data structure; [EADDRNOTAVAIL] when an attempt is made to create a socket with a network address for whichno network interface exists. SEE ALSO bsdsocket.library/send(), bsdsocket.library/recv(), inet, ip HISTORY Theicmp protocol is originally from 4.3BSD. 190 Section D.1 AmiTCP/IP System Manual D.1.3 if NAME if- Network Interface to SANA-II devices DESCRIPTION Each network interface in the AmiTCP/IP corresponds to a path through which messages may be sent and received. A network interface usually has a SANA-II device driver associated with it, though the loopback interface, "lo", do not. The network interface inthe AmiTCP/IP (sana_softc) is superset of the BSD Unix network interface. When the network interface is first time referenced, AmiTCP/IP tries toopen the corresponding SANA-II device driver. If successful, a software interface to the SANA-II device is created. The "network/" prefix is added to the SANA-II device name, if needed. Once the interface has acquired its address, it is expected to install a routing table entry so that messages can be routed through it. TheSANA-II interfaces must be configured before they will allow traffic to flow through them. It is done after the interface is assigned a protocol address with a SIOCSIFADDR ioctl. Some interfaces may use the protocol address or a part of it as their hardware address. On interfaces where the network-link layer address mapping is static, only the network number is taken from the ioctl; theremainder is found in a hardware specific manner. On interfaces which provide dynamic network-link layer address mapping facilities (for example, Ethernets or Arcnets using ARP), the entire address specified in the ioctl is used. Thefollowing ioctl calls may be used to manipulate network interfaces. Unless specified otherwise, the request takes an ifreq structure as its parameter. This structure has the form struct ifreq - char ifr_name[IFNAMSIZ]; /* interface name (eg. "slip.device/0")*/ union - struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; short ifru_flags; " ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* end of p-to-p link */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ "; SIOCSIFADDR Set interface address. Following the address assignment, the ``initialization'' routine for the interface is called. SIOCGIFADDR Get interface address. SIOCSIFDSTADDR Set point to point address for interface. SIOCGIFDSTADDR Get point to point address for interface. System Manual AmiTCP/IP Section D.1 191 SIOCSIFFLAGS Set interface flagsfield. If the interface is marked down, any processes currently routing packets through the interface are notified. SIOCGIFFLAGS Get interface flags. SIOCGIFCONF Get interface configurationlist. This request takes an ifconf structure(see below) as a value-result parameter. The ifc_len field should be initially set to the sizeof the buffer pointed to by ifc_buf. On return itwill contain the length, in bytes, of the configuration list. /* * Structure used in SIOCGIFCONF request. * Used toretrieve interface configuration * for machine (useful for programs which * must know all networks accessible). */ struct ifconf - int ifc_len; /* size of associated buffer */ union - caddr_t ifcu_buf; struct ifreq *ifcu_req; " ifc_ifcu; #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ "; UNSUPPORTED IN AmiTCP/IP These standard BSD ioctl codes are not currently supported: SIOCADDMULTI Enable a multicast address for the interface. SIOCDELMULTI Disable a previouslyset multicast address. SIOCSPROMISC Toggle promiscuous mode. AmiTCP/IP EXTENSIONS Thefollowing ioctls are used to configure protocol and hardware specific properties of a sana_softc interface. They are used in the AmiTCP/IP only. SIOCSSANATAGS Set SANA-II specific properties with a tag list. SIOCGSANATAGS Get SANA-II specific properties into a wiretype_parameters structure and a user tag list. struct wiretype_parameters - ULONG wiretype; /* the wiretype of theinterface */ WORD flags; /* iff_flags*/ struct TagItem*tags; /* tag list userprovides */ 192 Section D.1 AmiTCP/IP System Manual "; SEE ALSO arp, lo, netutil/arp, netutil/ifconfig, , , System Manual AmiTCP/IP Section D.1 193 D.1.4 inet NAME inet - Internet protocol family SYNOPSIS #include #include DESCRIPTION TheInternet protocol family implements a collection of protocols which are centered around the Internet Protocol (IP) and which share a common address format. The Internet family provides protocol support for the SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW socket types. PROTOCOLS TheInternet protocol family is comprised of the Internet Protocol (IP), the Address Resolution Protocol (ARP), the Internet Control Message Protocol (ICMP), the Transmission Control Protocol (TCP), andthe User Datagram Protocol (UDP). TCPis used to support the SOCK_STREAM abstraction while UDP is used tosupport the SOCK_DGRAM abstraction; (SEE ALSO tcp, SEE ALSO udp). A raw interface to IP is available by creating an Internet socket of type SOCK_RAW; (SEE ALSO ip). ICMP is used by the kernel to handle andreport errors in protocol processing. It is also accessible to user programs; (SEE ALSO icmp). ARP is used to translate 32-bit IP addresses into varying length hardware addresses; (SEE ALSO arp). The32-bit IP address is divided into network number and host number parts. It is frequency-encoded; the most significant bit is zero in Class A addresses, in which the high-order 8 bits are the network number. Class Baddresses have their high order two bits set to 10 anduse the highorder 16 bits as the network number field. Class C addresses have a 24-bit network number part of which the high order three bits are 110. Sites with a cluster of local networks may chose to use a single network number for the cluster; this is done byusing subnet addressing. The local (host) portion of the address isfurther subdivided into subnet number and host number parts. Within a subnet, each subnet appears to be an individual network; externally, the entire cluster appears to be a single, uniform network requiring only a single routing entry. Subnet addressing is enabled and examined by the following ioctl commands on a datagram socket in the Internet domain; they have the same form as the SIOCIFADDR (SEE ALSO if) command. SIOCSIFNETMASK Set interface network mask. The network mask defines the network part of the address; ifit contains more of the address than the address type would indicate, then subnets are in use. SIOCGIFNETMASK Get interface network mask. ADDRESSING IPaddresses are four byte quantities, stored in network byte order (the native Amiga byte order) 194 Section D.1 AmiTCP/IP System Manual Sockets in the Internet protocol family use the following addressing structure: struct sockaddr_in - short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; "; Functions in bsdsocket.library are provided to manipulate structures ofthis form. Thesin_addr field of the sockaddr_in structure specifies a local or remote IP address. Each network interface has its own unique IP address. The special value INADDR_ANY may be used in this field to effect "wildcard" matching. Given in a bind() call, this value leaves the local IP address of the socket unspecified, so that the socket will receive connections or messages directed at any of the valid IP addresses of the system. This can prove useful when a process neither knows nor cares what the local IP address is or when a process wishes to receive requests using all of its network interfaces. Thesockaddr_in structure given in the bind() call must specify an in_addr value of either IPADDR_ANY or one of the system's valid IP addresses. Requests to bind any other address will elicit theerror EADDRNOTAVAIL. When a connect() call is made for a socket that has a wildcard local address, the system sets the sin_addr field of the socket to the IP address of the network interface that thepackets for that connection are routed via. Thesin_port field of the sockaddr_in structure specifies a port number used by TCP or UDP. The local port address specified in a bind() call is restricted to be greater than IPPORT_RESERVED (defined in ) unless the creating process is running asthe super-user, providing a space of protected port numbers. In addition, the local port address must not be in use by any socket of same address family and type. Requests to bind sockets to port numbers being used by other sockets return the error EADDRINUSE. If thelocal port address is specified as 0, then the system picks a unique port address greater than IPPORT_RESERVED. A unique local port address is also picked when a socket which is not bound is used ina connect() or send() call. This allows programs which do not care which local port number is used to set up TCP connections by sim- ply calling socket() and then connect(), and to send UDP datagrams with a socket() call followed by a send() call. Although this implementation restricts sockets to unique local port numbers, TCP allows multiple simultaneous connections involving the same local port number so long as the remote IP addresses or port numbers are different for each connection. Programs may explicitly override the socket restriction by setting the SO_REUSEADDR socket option with setsockopt (see getsockopt()). SEE ALSO bsdsocket.library/bind(), bsdsocket.library/connect(), System Manual AmiTCP/IP Section D.1 195 bsdsocket.library/getsockopt(), bsdsocket.library/IoctlSocket(), bsdsocket.library/send(), bsdsocket.library/socket(), bsdsocket.library/gethostent(), bsdsocket.library/getnetent(), bsdsocket.library/getprotoent(), bsdsocket.library/getservent(), bsdsocket.library/inet_addr(), arp, icmp, ip, tcp, udp Network Information Center, DDN Protocol Handbook (3 vols.), Network Information Center, SRI International, Menlo Park, Calif., 1985. A AmiTCP/IP Interprocess Communication Primer WARNING TheInternet protocol support is subject to change as the Internet protocols develop. Users should not depend on details of the current implementation, but rather the services exported. 196 Section D.1 AmiTCP/IP System Manual D.1.5 ip NAME ip- Internet Protocol SYNOPSIS #include #include int socket(AF_INET, SOCK_RAW, proto) DESCRIPTION IPis the transport layer protocol used by the Internet protocol family. Optionsmay be set at the IP level when using higher-level protocols that are based on IP (such as TCP and UDP). It may also be accessed through a ``raw socket'' when developing new protocols, or special purpose applica- tions. A single generic option is supported at the IP level, IP_OPTIONS, that may be used to provide IP options to be transmitted in the IP header of each outgoing packet. Options are set with setsockopt() andexamined with getsockopt(). The format of IP options to be sent isthat specified by the IP protocol specification, with one exception: the list of addresses for Source Route options must include the first-hop gateway at the beginning of the list of gateways. The first-hop gateway address will be extracted from the option list and the size adjusted accordingly before use. IP options may be used with any socket type in the Internet family. RawIP sockets are connectionless, and are normally used with the sendto and recvfrom calls, though the connect() call may also be used to fix the destination for future packets (in which case the recv() and send() system calls may be used). Ifproto is 0, the default protocol IPPROTO_RAW is used for outgoing packets, and only incoming packets destined for that protocol are received. If proto is non-zero, that protocol number will be used onoutgoing packets and to filter incoming packets. Outgoing packets automatically have an IP header prepended to them (based on the destination address and the protocol number the socket iscreated with). Incoming packets are received with IP header and options intact. DIAGNOSTICS A socket operation may fail with one of the following errors returned: [EISCONN] when trying to establish a connection ona socket which already has one, orwhen trying to send a datagram with the destination address specified and the socket is already connected; [ENOTCONN] when trying tosend a datagram, but no destination address is specified, andthe socket hasn't been System Manual AmiTCP/IP Section D.1 197 connected; [ENOBUFS] when the system runs out of memory for aninternal data structure; [EADDRNOTAVAIL] when an attempt is made to create a socket with a network address for whichno network interface exists. Thefollowing errors specific to IP may occur when setting or getting IP options: [EINVAL] An unknown socket option name was given. [EINVAL] The IP option field was improperly formed; an option field was shorterthan the minimum value or longer than the option buffer provided. SEE ALSO bsdsocket.library/getsockopt(), bsdsocket.library/send(), bsdsocket.library/recv(), icmp, inet HISTORY Theip protocol appeared in 4.2BSD. 198 Section D.1 AmiTCP/IP System Manual D.1.6 lo NAME lo- Software Loopback Network Interface SYNOPSIS pseudo-device loop DESCRIPTION Theloop interface is a software loopback mechanism which may be used for performance analysis, software testing, and/or local communication. There is no SANA-II interface associated with lo. Aswith other network interfaces, the loopback interface must have network addresses assigned for each address family with which it is tobe used. These addresses may be set or changed with the SIOCSIFADDR ioctl. The loopback interface should be the last interface configured, as protocols may use the order of configuration as an indication of priority. The loopback should never be configured first unless no hardware interfaces exist. DIAGNOSTICS "lo%d: can't handle af%d." Theinterface was handed a message with ad- dresses formatted in an unsuitable address family; the packet was dropped. SEE ALSO inet, if, netutil/ifconfig BUGS Older BSD Unix systems enabled the loopback interface automatically, using a nonstandard Internet address (127.1). Use ofthat address is now discouraged; a reserved host address for the local network should be used instead. System Manual AmiTCP/IP Section D.1 199 D.1.7 routing NAME routing - system supporting for local network packet routing DESCRIPTION Thenetwork facilities provided general packet routing, leaving routing table maintenance to applications processes. A simple set of data structures comprise a ``routing table'' used in selecting the appropriate network interface when transmitting packets. This table contains a single entry for each route to a specific network or host. A user process, the routing daemon, maintains this data base with the aid of two socket specific ioctl commands, SIOCADDRT and SIOCDELRT. Thecommands allow the addition and deletion of a single routing table entry, respectively. Routing table manipulations may only be carried out by super-user. A routing table entry has the following form, as defined in : struct rtentry - u_long rt_hash; struct sockaddr rt_dst; struct sockaddr rt_gateway; short rt_flags; short rt_refcnt; u_long rt_use; struct ifnet *rt_ifp; "; with rt_flags defined from: #define RTF_UP 0x1 /* route usable */ #define RTF_GATEWAY 0x2 /* destination is a gateway */ #define RTF_HOST 0x4 /* host entry (net otherwise) */ Routing table entries come in three flavors: for a specific host, for all hosts on a specific network, for any destination notmatched by entries of the first two types (a wildcard route). When the system is booted, each network interface autoconfigured installs a routing table entry when it wishes tohave packets sent through it. Normally the interface specifies the route through it is a ``direct'' connection to thedestination host or network. If the route is direct, the transport layer of a protocol family usually requests the packet be sent to the same host specified in the packet. Otherwise, the interface may be requested to address the packet to an entity different from the eventual recipient (that is, the packet is forwarded). Routing table entries installed by a user process may not specify the hash, reference count, use, or interface fields; these are filled in by the routing routines. If a route is in usewhen it is deleted (rt_refcnt is non-zero), the resources associated with it will not be reclaimed until all references toit are removed. 200 Section D.1 AmiTCP/IP System Manual Therouting code returns EEXIST if requested to duplicate an existing entry, ESRCH if requested to delete a non-existent entry, or ENOBUFS if insufficient resources were available to install a new route. Thert_use field contains the number of packets sent along the route. This value is used to select among multiple routes to thesame destination. When multiple routes to the same destination exist, the least used route is selected. A wildcard routing entry is specified with a zero destination address value. Wildcard routes are used only when the system fails to find a route to the destination host and network. Thecombination of wildcard routes and routing redirects can provide an economical mechanism for routing traffic. SEE ALSO bsdsocket.library/IoctlSocket(), netutil/route System Manual AmiTCP/IP Section D.1 201 D.1.8 tcp NAME tcp- Internet Transmission Control Protocol SYNOPSIS #include #include int socket(AF_INET, SOCK_STREAM, 0) DESCRIPTION TheTCP protocol provides reliable, flow-controlled, two-way transmission of data. It is a byte-stream protocol used to support theSOCK_STREAM abstraction. TCP uses the standard Internet address format and, in addition, provides a per-host collection of ``port addresses''. Thus, each address is composed of an Internet address specifying the host and network, with a specific TCP port on the host identifying the peer entity. Sockets utilizing the tcp protocol are either ``active'' or ``passive''. Active sockets initiate connections to passive sockets. By default TCP sockets are created active; to create a passive socket the listen() bsdsocket.library function call must be used after binding the socket with the bind() bsdsocket.library function call. Only passive sockets may use the accept() call to accept incoming connections. Only active sockets may use the connect() call to initiate connections. Passive sockets may ``underspecify'' their location to match incoming connection requests from multiple networks. This technique, termed ``wildcard addressing'', allows a single server to provide service to clients on multiple networks. To create a socket which listens on all networks, the Internet address INADDR_ANY must bebound. The TCP port may still be specified at this time; if the port is not specified the bsdsocket.library function will assign one. Once a connection has been established the socket's address is fixed by the peer entity's location. The address assigned the socket is the address associated with the network interface through which packets are being transmitted and received. Normally this address corresponds to the peer entity's network. TCPsupports one socket option which is set with setsockopt() and tested with getsockopt(). Under most circumstances, TCP sends data when it is presented; when outstanding data has not yet been acknowledged, it gathers small amounts of output to be sent in a single packet once an acknowledgement is received. For a small number of clients, such as X Window System functions that send a stream of mouse events which receive no replies, this packetization may cause significant delays. Therefore, TCP provides a boolean option, TCP_NODELAY (from , to defeat this algorithm. Theoption level for the setsockopt call is the protocol number for TCP, available from getprotobyname(). Options at the IP transport level may be used with TCP; SEE ALSO ip. 202 Section D.1 AmiTCP/IP System Manual Incoming connection requests that are source-routed are noted, and thereverse source route is used in responding. DIAGNOSTICS A socket operation may fail with one of the following errors returned: [EISCONN] when trying to establish a connection ona socket which already has one; [ENOBUFS] when the AmiTCP/IP runs out of memory foran internal data structure; [ETIMEDOUT] when a connection was dropped due to excessive retransmissions; [ECONNRESET] when the remote peerforces the connection to be closed; [ECONNREFUSED] when the remote peer actively refuses connection establishment (usually because no process is listening to the port); [EADDRINUSE] when an attempt is made to create a socket with a port which has already been allocated; [EADDRNOTAVAIL] when an attempt is made to create a socket with a network address for whichno network interface exists. SEE ALSO bsdsocket.library/getsockopt(), bsdsocket.library/socket(), bsdsocket.library/bind(), bsdsocket.library/listen(), bsdsocket.library/accept(), bsdsocket.library/connect(), inet, ip,, , HISTORY Thetcp protocol stack appeared in 4.2BSD. System Manual AmiTCP/IP Section D.1 203 D.1.9 udp NAME udp- Internet User Datagram Protocol SYNOPSIS #include #include int socket(AF_INET, SOCK_DGRAM, 0) DESCRIPTION UDPis a simple, unreliable datagram protocol which is used to support the SOCK_DGRAM abstraction for the Internet protocol family. UDPsockets are connectionless, and are normally used with the sendto() and recvfrom() calls, though the connect() call may also be used to fix the destination for future packets (in which case the recv() and send() function calls may be used). UDPaddress formats are identical to those used by TCP. In particular UDP provides a port identifier in addition to the normal Internet address format. Note that the UDP port space is separate from the TCP port space (i.e. a UDP port may not be ``connected'' to a TCP port). In addition broadcast packets may be sent (assuming the underlying network supports this) by using a reserved ``broadcast address''; this address is network interface dependent. Options at the IP transport level may be used with UDP; SEE ALSO ip. DIAGNOSTICS A socket operation may fail with one of the following errors returned: [EISCONN] when trying to establish a connection ona socket which already has one, orwhen trying to send a datagram with the destination address specified and the socket is already connected; [ENOTCONN] when trying tosend a datagram, but no destination address is specified, andthe socket hasn't been connected; [ENOBUFS] when the system runs out of memory for an internal data structure; [EADDRINUSE] when an attempt is made to create a socket with a port which has already been allocated; [EADDRNOTAVAIL] when an attempt is made to create a socket with a network address for whichno network interface exists. SEE ALSO bsdsocket.library/getsockopt(), bsdsocket.library/recv(), bsdsocket.library/send(), bsdsocket.library/socket(), inet, ip 204 Section D.1 AmiTCP/IP System Manual HISTORY Theudp protocol appeared in 4.2BSD. Glossary API Application Program Interface. Standard function calls, messages and devices used in application level programs. Arcnet Yet another network type, transfer rate 5Mbits/sec. ARexx ARexx is a specific implementation of the Rexx language forthe Amiga. Rexx itself is a script language with superb power/simplicity ratio, originally developed for some IBM mainframe systems. ARP Address Resolution Protocol. A communication protocol used tomap protocol address to network address dynamically. For example, ARP is used to map DARPA Internet addresses into Ethernet addresses. AutoDoc Document generated automagically from comments included in program source code. Mainly used to describe shared library functions in AmigaOS. See [RKM Inc & ADoc 1992 ]. BSD Berkeley Software Distribution. Family of UNIX versions for the DEC (VAX) and PDP-11 developed by Bill Joy and others at Berzerkeley starting around 1980, incorporating paged virtual memory, TCP/IP networking enhancements, and many other features. The BSD versions (4.1, 4.2, and 4.3) and the commercial versions derived from them (SunOS, ULTRIX, and Mt. Xinu) held the technical lead in the UNIX world until AT&T's successful standardization efforts after about 1986, and are still widely popular. BSDSS BSD Single Server is operating system server in Mach operating system where all UNIX services are in single binary. (D)ARPA Internet The collection of networks using internet protocols. (D)ARPA Internet originated from a research project sponsored by the (Defense) Advanced Research Project Agency. Daemon 'A deified being', program that lives forever on system, or reincarnates every time it is needed. Performs its requested task promptly and goes back to sleep. Data link layer Protocol layer providing data transfer between machines in same physical network. DIS First stage in ISO's standardization. (Discussion) 205 206 Section D.1 AmiTCP/IP System Manual Ethernet 10Mbit/sec physical network interface. Developed by Xerox in Palo Alto late 70s. In 1982 published with Digital and Intel as ESPEC1. ESPEC2 was approved as basic specification for LANs which employed the carrier sense multiple access with collision detection by IEEE 802.3 committee. Heavily derived version was later published by ISO as DIS 8802/3. Original has only version for 50 coaxial cable, 10BASE5 ``Thick Ether'', but nowadays has also for thinner coaxial cable, 10BASE2 ``Thin Ether'', twisted pair, 10BASET and fibre, 10BASEF. There are also broadband, 10BROAD36, and slower, 1Mbit/s 1BASE5, versions. EXEC AmigaOS EXECutive. Provides the basic kernel functions, such as task scheduling, memory management, concurrency control, message ports, public library lists etc. Frame Data unit transferred between data link layer protocol entities. ICMP Internet Message Control Protocol. A host-to-host communication protocol used in the DARPA Internet for reporting errors and controlling the operation of IP. IEEE the Institute of Electrical and Electronics Engineers Inetd the Internet super server. A server that listens to the network and launches other server processes when needed. IO request An Amiga standard message format to discuss with devices. IO requests are sent by Exec function BeginIO() to the device driver. Completed IO requests are sent back to the reply port specified in IO request. IP Internet Protocol. The network-layer communication protocol used in the DARPA Internet. IP is responsible for host-to-host addressing and routing, packet forwarding, and packet fragmentation and reassembly. ISO International Organization for Standardization Jargon A formal technical vocabulary of various subjects. Also hackish slang or mumbo jumbo is referred as jargon [Raymond 1992 ]. Library base In AmigaOS shared library is accessed via a library base pointer. On the negative side (relative to the base pointer) there is jump table to the library functions and on the positive side -- library data the functions can use. Log It is usually useful to record information. If something hasgone wrong, one may found information to remove cause of failure. A log is usually a file, where information is written. Mbuf Memory BUFfer. Data storage unit inside BSD networking implementation. Message Data unit transferred between applications using network services. System Manual AmiTCP/IP Section D.1 207 MTU Maximum Transfer Unit. The amount of data that underlying network can transfer in one block. NET/2 Latest (by now) BSD Unix release. Network File System A filesystem share protocol which enables other computers use disks on other host over network. Usually uses UDP protocol for transfering files, but also TCP-based version exists. Developed by Sun Microsystems Inc., and developed to ``Industrial Standard'' in *IX environment. Described in detail ``Networking on the Sun Workstation'' Octet A unit of eigth bits. Used in communication to overcome problem that byte is not allways eigth bits (althoug this is nowadays very rare situation.) Packet Data unit transferred between network layer protocol entities. panic() Function executed after lethal failure in Unix kernel. PPP Point-to-Point Protocol which allows multiple protocols to be transferred on the same line. It is also more flexible than SLIP. Protocol stack A network protocol stack is a layerof software that network applications use to address particular processes on remote machines. The AmiTCP/IP is such a protocol stack using TCP/IP protocols. RARP Reverse Address Resolution Protocol maps network addresses to protocol addresses dynamically. RFC Request For Comments. Freely available standards for networking. They are mostly available online from nic.ddn.mil with FTP or Kermit. RKM Rom Kernel reference Manuals are the most authoritative AmigaOS references, see [RKM Libraries 1992 ] for example. SANA-II A standard for an Amiga software interface between networking hardware and network protocol stacks (or for software tools such as network monitors). SLIP Serial Line Internet Protocol. Data encapsulation protocol used to transmit IP packets over point-to-point serial lines. Socket An abstraction for endpoint of communication. TLA Three Letter Acronym, a mnemonic and mystic abbreviation which is coined to confuse acolytes. TCP Transmission Control Protocol. A connection-oriented transport protocol used in the DARPA Internet. TCP provides for the reliable transfer of data, as well as the out-of-band indication of urgent data. TCP/IP The whole protocol stack, which implements at least the Internet protocols required is often expressed as the two most commonly used, TCP/IP 208 Section D.1 AmiTCP/IP System Manual UDP User Datagram Protocol. A simple unreliable datagram protocolused in the DARPA Internet. UDP provides only peer-to-peer addressing and optional data checksum. Wire type is the physical layer protocol type. Different wire types are for instance Arcnet, Ethernet, IEEE 802.3, PPP and SLIP. Bibliography [Comer 1988] Comer, D. E., Internetworking With TCP/IP Vol I: Principles, Protocols and Architecture, Prentice--HallInternational, 382 p. [Comer and Stevens 1991] Comer, D. E. and Stevens, D. L., Internetworking With TCP/IP VolII: Design, Implementation, and Internals, Prentice--Hall International, 524 p. [Finlayson et al 1984] Finlayson, R.,Mann, T., Mogul, J. and Theimer, M., ``A ReverseAddress Resolution Protocol,'' RFC 903, 4 p. [Holloway 1991] Holloway, T., ``Object Oriented Amiga EXEC,'' BYTE, vol. 16,issue 1, pp. 329--334, January 1991. [Jacobson 1990] Jacobson, V., ``Compressing TCP/IP Headers for Low-speed Serial Links,'' RFC 1144, 43 p. [Leffler et al 1989] Leffler, S. J.,McKusick, M. K., Karels, M. J. and Quarterman,J. S., The Design and Implementationof the 4.3BSD UNIX Operating System, Addison--Wesley 471 p. [Leffler et al 1991a] Leffler, S. J.,Fabry, R. S., Joy, W. N., Lapsley, P., Miller, S., Torek, C., ``An Advanced 4.3BSDInterprocess Communication Tutorial'' UNIXProgrammer's Supplementary Documents (PS1), net/2 Berkeley Software Distribution, Computer Systems Research Group, Univ. of California, Berkeley, 53 p. [Leffler et al 1991b] Leffler, S. J.,Joy, W. N., Fabry, R. S. and Karels, M. J.,``Networking Implementation Notes, 4.3BSD Edition,'' UNIX System Manager's Manual (SMM), net/2 Berkeley Software Distribution, Computer Systems Research Group, Computer Science Division, Univ. of California, Berkeley, 26 p. [Plummer 1982] Plummer, D. C.,``An Ethernet Address Resolution Protocol,'' RFC826, 10 p. 209 210 Section D.1 AmiTCP/IP System Manual [Postel 1980] Postel, J., ``User Datagram Protocol,'' RFC 768, 3 p. [Postel 1981a] Postel, J. ed.,``Internet Protocol,'' RFC 791, 45 p. [Postel 1981b] Postel, J., ``Internet Control Message Protocol,'' RFC792, 21 p. [Postel 1981c] Postel, J. ed.,``Transmission Control Protocol,'' RFC793, 85 p. [Raymond 1992] Raymond, Eric ed., ``The Jargon File 2.9.9'', the on-line hacker Jargon File, version 2.9.9, 01 APR 1992. [Reynolds 1990] Reynolds, JoyceK., ``Assigned Numbers'', RFC 1060, 86 p. [RKM Libs & Devs 1989] Commodore--Amiga Inc., Amiga ROM Kernel Reference Manual: Librariesand Devices, Addison Wesley,956 p. [RKM Libraries 1992] Commodore--Amiga Inc., Amiga ROM Kernel Reference Manual: Libraries, 3rd ed., Addison Wesley, 967 p. [RKM Inc & ADoc 1992] Commodore--Amiga Inc., Amiga ROM Kernel Reference Manual: Includes& AutoDocs, 3rd ed., Addison Wesley,471 p. [SANA-II 1992] Amiga Networking Group, ``SANA-II Network Device Driver Specification - Rev 1.0 23-Apr-92,'' published at Fred Fish-collection disk#673. [SANA-II 1992 add] Amiga Networking Group, ``Addenda to SANA-II Network DeviceDriver Specification,'' published at SANA-II Developer Support Package, May 21, 1992. [Stevens 1990] Stevens, W., R., UNIX network programming, Prentice Hall,772 p. [Winsock 1992] Hall, M., Towfiq, M., Arnold, G., Trendwell, D., Sanders, H., ``Windows Sockets An Open Interface for Network Programming under Microsoft Windows Version 1.0 Rev.A'' 11 June, 1992, 124 p. The RFC documents are stored online on nic.ddn.mil, from where they can be downloaded with anonymous FTP. The file /rfc/rfc-index.txt contains index to all published RFCs. The BSD documents are carried by many FTP sites, for example nic.funet.fi.